I have a classic diamond inheritance problem where
A
/ \
B C
\ /
D
are all interfaces, and I have
AImpl(A)
| \
| \
BImpl(B) CImpl(C)
| \
| \
DImpl(B,C) \
| F(C)
|
E(B,C)
where class E implements both interfaces B and C, but F implements only interface C.
Due to the lack of multiple inheritance, I currently have duplicated functionality in DImpl and CImpl.
I just fixed a bug in CImpl, but forgot to do the same for DImpl. Obviously remembering to always copy code from CImpl to DImpl and vice versa is not very sustainable as the code base keeps growing. Are there any established best practices for putting the shared code of both in a single place, despite the disallowance of multiple inheritance?
EDIT -- Solution with multiple inheritance would have been to have DImpl inherit CImpl.cFunction() instead of redefining DImpl.cFunction as a copy of CImpl.cFunction
EDIT 2 -- Sample code:
public interface Animal {
public void eat();
}
public interface FlyingAnimal extends Animal {
public void fly();
}
public interface RunningAnimal extends Animal {
public void run();
}
public interface Monster extends FlyingAnimal, RunningAnimal {
public void roar();
}
public class AnimalImpl implements Animal {
#Override
public void eat() {
...
}
}
public class FlyingAnimalImpl extends AnimalImpl implements FlyingAnimal {
#Override
public void fly() {
...
}
}
public class RunningAnimalImpl extends AnimalImpl implements RunningAnimal {
#Override
public void run() {
...
}
}
public class MonsterImpl extends FlyingAnimalImpl implements Monster {
#Override
public void run() {
...
}
#Override
public void roar() {
...
}
}
public class ScaryMonster extends MonsterImpl implements Monster {
public void sneakAround() {
...
}
}
public class Human extends RunningAnimalImpl implements RunningAnimal {
public void scream() {
...
}
}
Now if I find a bug in RunningAnimalImpl.run() and I fix it, I have to remember to copy the fix over to MonsterImpl.run().
This is a very poor design. You should not have a diamond structure in the first place just because it is possible in interfaces.
One of the basic principle of OOP is
Prefer composition over inheritance!
What I am saying is you don't need interface D at all. Wherever you need to use DImpl simply provide reference to interface A and then based on your runtime need pass BIml or CImpl instance to it. That way all you have to change is BImpl code or CImpl code for bug fix and it will be used anywhere you are using DImpl instance today.
As per your comment the code would be something like -
public class ScaryMonster {
Animal animal;
public ScaryMonster(Animal animal) {
this.animal = animal;
}
public void fly() {
if(animal instanceof FlyingAnimal ) {
((FlyingAnimal )animal).fly();
}
else {
throw new Exception("This mosnter cannot fly");
}
}
public void run() {
if(animal instanceof RunningAnimal ) {
((RunningAnimal )animal).run();
}
else {
throw new Exception("This mosnter cannot run");
}
}
public void sneakAround() {
...
}
}
If you want your monster to both fly and run pass instance of MonsterImpl to the constructor. Note now ScaryMonster does not extend or implement anything.
This is what I am saying - Prefer composition over Inheritance!.
In Java 8 you can implement default methods within interfaces so if you have an interface with common implementations just define them inside of the interface and override them whenever you need to change it up a bit. Of course this is assuming you are using Java 8.
For example:
public interface A {
default void cFunction(){
System.out.println("Calling A.cFunction");
}
}
public class DImpl implements A {
}
DImpl can call cFunction and it will default to calling the interfaces implementation.
In the case which 2 interfaces have a method with the same signature you can call them by referencing the interface name along with the method such as A.super.cFunction()
More meaningful example:
public interface Driveable {
default void start(Vehicle vehicle){
System.out.println("Starting my driveable thing");
vehicle.mileage++;
}
}
public interface Machine {
default void start(){
System.out.println("Starting my machine");
}
}
public class ElectricCar extends Vehicle implements Driveable, Machine {
public void start(){
Driveable.super.start(this);
}
}
public class DIYCar extends Vehicle implements Driveable, Machine {
public void start(){
System.out.println("instant fire");
}
}
As you can see you can implement a default method in your interface and use it within your concrete class. In this scenario an ElectriCar is Driveable and a Machine but we want it to use the Driveable start() method because at the end of the day no matter how many machines (computers) are in our car, we still just want to drive it.
This is just an example and although the example may be a bit strange I hope it helps get the point across of being able to implement default methods.
UPDATE for your example source:
In your case of your Monster and Animal being able to run, you should have a RunnableCreature interface with an implementation of run(). This way if a Monster and Animal run the same they can reference the default run() method, otherwise it can override it and implement its own.
If you need your default method to manipulate variables two (or more) of your classes that have the same run() method would have common attributes and therefore should have a common base class. You can pass this base class to the default method and manipulate its variables as needed.
Don't implement C in D, instead of inheritance compose it within D. In that way you dont duplicate your code and have just one implementation of C.
If you somehow needs to inherit from C (which i think you would need to review design then), then i would still suggest you compose C and implement all the methods of C within D and delegate calls via composed object.
A common alternative would be to use composition instead of inheritance. Does it make sense to say that D is a B and is also a C? Does D really need to expose every public method contained in B and C? If the answer to any of these questions is no, then inheritance is not the right tool for the job.
If you want to read further about the advantages of composition, check this chapter from Effective Java: Favor composition over inheritance
Related
Which access modifier, in an abstract class, do I have to use for a method,
so the subclasses can decide whether it should be public or not? Is it possible to "override" a modifier in Java or not?
public abstract class A {
??? void method();
}
public class B extends A {
#Override
public void method(){
// TODO
}
}
public class C extends B {
#Override
private void method(){
// TODO
}
}
I know that there will be a problem with static binding, if
someone calls:
// Will work
A foo = new B()
foo.method();
// Compiler ?
A foo = new C();
foo.method();
But maybe there is another way. How I can achieve that?
It is possible to relax the restriction, but not to make it more restrictive:
public abstract class A {
protected void method();
}
public class B extends A {
#Override
public void method(){ // OK
}
}
public class C extends A {
#Override
private void method(){ // not allowed
}
}
Making the original method private won't work either, since such method isn't visible in subclasses and therefore cannot be overriden.
I would recommend using interfaces to selectively expose or hide the method:
public interface WithMethod {
// other methods
void method();
}
public interface WithoutMethod {
// other methods
// no 'method()'
}
public abstract class A {
protected void method();
}
public class B extends A implements WithMethod {
#Override
public void method(){
//TODO
}
}
public class C extends B implements WithoutMethod {
// no 'method()'
}
... then only work with the instances through the interfaces.
When overriding methods, you can only change the modifier to a wider one, not vice versa. For example this code would be valid:
public abstract class A {
protected void method();
}
public class B extends A {
#Override
public void method() { }
}
However, if you try to narrow down the visibility, you'd get a compile-time error:
public abstract class A {
protected void method();
}
public class B extends A {
#Override
private void method() {}
}
For your case, I'd suggest to make C not implementing A, as A's abstraction implies that there's a non-private method():
public class C {
private void method(){
//TODO
}
}
Another option is to make the method() implementation in C throwing a RuntimeException:
public class C extends A {
#Override
public void method(){
throw new UnsupportedOperationException("C doesn't support callbacks to method()");
}
}
What you are asking for is not possible for very good reasons.
The Liskov substitution principle basically says: a class S is a subclass of another class T only then, when you can replace any occurrence of some "T object" with some "S object" - without noticing.
If you would allow that S is reducing a public method to private, then you can't do that any more. Because all of a sudden, that method that could be called while using some T ... isn't available any more to be called on S.
Long story short: inheritance is not something that simply falls out of the sky. It is a property of classes that you as the programmer are responsible for. In other words: inheritance means more than just writing down "class S extends T" in your source code!
This is impossible because of the polymorphism. Consider the following. You have the method in class A with some access modifier which is not private. Why not private? Because if it was private, then no other class could even know of its existence. So it has to be something else, and that something else must be accessible from somewhere.
Now let's suppose that you pass an instance of class C to somewhere. But you upcast it to A beforehand, and so you end up having this code somewhere:
void somewhereMethod(A instance) {
instance.method(); // Ouch! Calling a private method on class C.
}
One nice example how this got broken is QSaveFile in Qt. Unlike Java, C++ actually allows to lower access privileges. So they did just that, forbidding the close() method. What they ended up with is a QIODevice subclass that is not really a QIODevice any more. If you pass a pointer to QSaveFile to some method accepting QIODevice*, they can still call close() because it's public in QIODevice. They “fixed” this by making QSaveFile::close() (which is private) call abort(), so if you do something like that, your program immediately crashes. Not a very nice “solution”, but there is no better one. And it's just an example of bad OO design. That's why Java doesn't allow it.
Edit
Not that I missed that your class is abstract, but I also missed the fact that B extends C, not A. This way what you want to do is completely impossible. If the method is public in B, it will be public in all subclasses too. The only thing you can do is document that it shouldn't be called and maybe override it to throw UnsupportedOperationException. But that would lead to the same problems as with QSaveFile. Remember that users of your class may not even know that it's an instance of C so they won't even have a chance to read its documentation.
Overall it's just a very bad idea OO-wise. Perhaps you should ask another question about the exact problem you're trying to solve with this hierarchy, and maybe you'll get some decent advises on how to do it properly.
Here is a part of the #Override contract.
The answer is : there isn't any possibility to achieve what you have.
The access level cannot be more restrictive than the overridden
method's access level. For example: if the superclass method is
declared public then the overridding method in the sub class cannot be
either private or protected.
This is not a problem concerning abstract classes only but all classes and methods.
THEORY:
You have the determined modifiers order:
public <- protected <- default-access X<- private
When you override the method, you can increase, but not decrease the modifier level. For example,
public -> []
protected -> [public]
default-access -> [public, default-access]
private -> []
PRACTICE:
In your case, you cannot turn ??? into some modifier, because private is the lowest modifier and private class members are not inherited.
This question was asked to me in an interview. Tired of googling here I am.
I have an interface with 100 methods. I don't want to implement all those 100 methods in a single class. Is there any way I could implement these 100 methods by using more than one class and not repeating the implementation ?
For Example :
Class A implements first 10 methods(only).
Class B implements next 10 methods(only) and so on.
Note :
1. All the classes which implements the interface must be concrete.
As far as my knowledge on java this isn't possible. He mentioned about adapter when he asked me this question. That made me think that there's a way to do it.
Can anybody clarify me on this ?
Write an adapter with empty implementation of the 100 methods
class Adapter{
//write your empty implementations here as similar to KeyListener in Java
// They have written a keyAdapter and make use of key adapter.
}
ie) class Adapter implements interface1{
public void method1(){}
public void method2(){}
.....
}
You can extend the adapter class in some other class and just override the methods.
class A extedns Adapter{
public void method1(){
}
}
ie)
The concept you describe is called partial classes and Java does not have such a concept.
Here is a similar answer: A way to implement partial classes in java
If you use Java 8 , you can define default implementations in the interface for the 100 methods like :
public interface MyInterface{
void methodA();
int methodB();
default boolean methodC(String name) {
return name.equals("Default");
}
}
Then in your concrete classes you only implements the methods you want. All other not overriden methods will use the default implementation from the interface.
You will have to write 100 default implementations in the interface but it will save you the need to also write 100 implementations in every concrete class implementing that interface.
Again, this is only available since Java 8.
Write all the classes (A, B, C, D, E each implement 20 methods) witch extend one another without implementing the interface I:
I
|
A <- B <- C <- D <- E
And only the last one implements the interface.
Simpler exemple with only 2 methods:
public interface I {
void a();
void b();
}
public class A {
public void a() {
}
}
public class B extends A implements I {
public void b() {
}
}
If the interface methods defined with default implementation ;
public interface I {
default void a(){
//implementation
}
default void b(){
//implementation
}
default void c(){
//implementation
}
//97 more
}
public class A implements I{
#override
public void a() {
}
}
public class B extends A {
#override
public void b() {
}
public class C extends B {
#override
public void c() {
}
}
Even without inheritance classes can be independent from each other and they can provide implementation for different methods
You are correct - any concrete class must implement all methods, so the only way you can not do it is either extend the class that implements given interface and override some of the methods in subclass or implement methods calling implementations from other classes
More than a few times I've found my self working with a class that is closed (I can't modify it) that I wish implemented a nice narrow interface particular to my needs. My client code is supposed to own the interface but I know of no mechanism to announce that this closed class is a implementation of my narrowed interface.
I'm trying to allow this class to be passed in (dependency injected) to my code (composition) but also anything else that can support the narrowed interface. In other languages duck typing makes this trivial. I'm in java though, so I'm expecting to have to write a whole other class just to wrap the closed class to make this happen. Is there a way I'm missing?
Thanks
EDIT to address dupe:
The Interface Segregation Principle offers no mention of the closed class issue which is the point of this question. Please reconsider marking as dupe of this particular question.
This question:
Interface Segregation Principle- Program to an interface, has a good example of the interface segregation principle:
class A {
method1()
method2()
// more methods
method10()
}
class B {
A a = new A()
}
will become
interface C {
method1()
method2()
}
class A implements C{
method1()
method2()
// more methods
method10()
}
class B {
C c = new A()
}
But note how it requires a change to class A. If A is closed to modification how do I accomplish the same thing cleanly?
Depending on the situation, one possibility is to wrap all classes in a wrapper class that exposes the said interface, I mean something like this:
public class UnmodifyableObject {
public void method1();
public void method2();
public void method3();
public void method4();
}
Then you want the interface to look like:
public interface MyInterface {
public void method1();
public void method2();
}
As a solution you can wrap your UnmodifyableObject in a WrappedUnmodifyableObject:
public class WrappedUnmodifyableObject implements MyInterface {
private final UnmodifyableObject unmodifyableObject;
public WrappedUnmodifyableObject(final UnmodifyableObject unmodifyableObject) {
this.unmodifyableObject = Objects.requireNonNull(unmodifyableObject, "unmodifyableObject");
}
#Override
public void method1() {
unmodifyableObject.method1();
}
#Override
public void method2() {
unmodifyableObject.method2();
}
public void method3() {
unmodifyableObject.method3();
}
public void method4() {
unmodifyableObject.method4();
}
}
It does nothing more than delegate all methods, and of course it implements the interface.
A few important things to note are that:
- You should use composition over inheritance, it might look easier to just extend the class, but you do not control that code, it may remove methods or it may even be final.
- This does mean you have to do quite some work.
- If you do not want to do the work yourself, you might need to look into tools to change the bytecode either before execution or before loading the class.
Usage of this object would be via:
UnmodifyableObject unmodifyableObject = someExternalMethodCall();
MyInterface myInterfaceObject = new WrappedUnmodifyableObject(unmodifyableObject);
Use one or more adapters. Adapters are a type of wrapper that changes the interface of the wrapped class without the need to change its source.
class A {
method1()
method2()
// more methods
method10()
}
interface SegregatedI1 {
method1();
}
interface SegregatedI2 {
method2();
method3();
}
class ASegregatedI1Adapter implements SegregatedI1 {
private final A a;
AI1Adapter(A a){
this.a = a;
}
public void method1(){
a.method1();
}
}
Note that A could be an interface or a final class. Also note that an adapter could implement more than one of the segregated interfaces, or you can have separate adapters for each (I'd prefer the latter to keep inline with single responsibility).
Mark Peters suggested simply extending the closed class to avoid the wrapper. Since he hasn't posted an answer based on it I'll write one up.
I normally avoid inheritance in favor of composition as a knee jerk reaction but in this case it really seems to have merit. The main reason being writing a wrapper simply ends up moving the sin of coding to an implementation from the client method into the wrapper. Thus the only thing gained is a level of indirection. If that's all we get and we can find an easier way to get it why not?
Here's some code that slaps a very narrow roleinterface on a very popular and very closed library class: ArrayList.
public class MainClass {
public static void main(String[] args) {
OpenArrayList<String> ls = new OpenArrayList<String>();
ShowClient client = new ShowClient(ls);
ls.add("test1");
client.show();
ls.add("test2");
client.show();
}
}
//Open version of ArrayList that can implement roleinterfaces for our clients
public class OpenArrayList<E> extends ArrayList<E> implements ShowState {
private static final long serialVersionUID = 1L;
}
//Roleinterface for ShowClient
public interface ShowState {
public int size();
public String toString();
}
//Show method programmed to a roleinterface narrowed specifically for it
public class ShowClient {
private ShowState ss;
ShowClient(ShowState ss) {
this.ss = ss;
}
void show() {
System.out.println( ss.size() );
System.out.println( ss.toString() );
}
}
So, if you're going to do Interface Segregation when using a class closed to modification is there a reason not to do it this way?
I'm still a beginner in java, but I try to write good code (obj oriented). However, I'm having a problem with the method removeFromWorld. I several approaches, but whatever I do I seem to break a "rule" of good programming practice.
I tried it with type-checking:
public class World{
private Set setGiraffes;
public void removeFromWorld(Animal animal){
if (isGiraffe(animal))
setGiraffes.remove((Giraffe) animal)
else if (isZebra(animal)){...}
else if ...
}
}
public abstract class Animal{..}
public class Giraffe extends Animal{..}
but heard that was a bad idea since it's impossible to add a new animal without changing existing methods. I considered moving removeFromWorld to Animal and overwriting it in each subclass, but since it's World using the sets, that seemed bad as well
I'm quite at a loss as for what would be an "elegant"/good solution.
You are absolutely right, this style of programming kills maintainability of your code right away.
There are two simple ways of handling this - implementing a visitor, and defining a Map based on Class<T>.
Here is an example of the first approach:
interface Visitor {
void visitGiraffe(Giraffe g);
void visitZebra(Zebra z);
}
abstract class Animal {
public abstract void accept(Visitor v);
}
class Giraffe extends Animal {
public void accept(Visitor v) {
v.visitGiraffe(this);
}
}
class Zebra extends Animal {
public void accept(Visitor v) {
v.visitZebra(this);
}
}
With this structure in hand, you can write your remover as follows:
void removeFromWorld(Animal a) {
a.accept(new Visitor() {
public void visitGiraffe(Giraffe g) {
setOfGiraffes.remove(g);
}
public void visitZebra(Zebra z) {
setOfZebras.remove(z);
}
});
}
The second relies on the ability of Java objects to produce their Class. Now instead of defining
Set<Giraffe> setOfGiraffes = ...
Set<Zebra> setOfZebras = ...
you can define
Map<Class,Set<Animal>> setOfAnimalByClass = ...
To access giraffes, you would do
setOfAnimalByClass.get(Giraffe.class).add(new Giraffe());
and so on. Then you can implement removeFromWorld like this:
void removeFromWorld(Animal a) {
a.accept(new Visitor() {
setOfAnimals.get(a.getClass()).remove(a);
});
}
Assuming all animals hava a removeFromWorld method but each child has a different version then the elegant solution is to make Animal an abstract class and removeFromWorld an abstract method. That way any class that extends Animal has to have its own removeFromWorld method (and cannot accidently use the generic Animal one). Whether you actually want to do that or not though will depend on your actual application
public interface Foo {
}
public class SpecificFoo implements Foo {
}
public interface SomeInterface {
void thisMethod(Foo someKindOfFoo);
}
public class SomeClass implements SomeInterface {
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
System.out.println("Dont go here please");
}
public void thisMethod(SpecificFoo specificFoo) {
// not into this function
System.out.println("Go here please");
}
}
public class SomeOlderClass {
public SomeOlderClass( SomeInterface inInterface ) {
SpecificFoo myFoo = new SpecificFoo();
inInterface.thisMethod(myFoo);
}
}
calling code:
SomeClass myClass = new SomeClass();
SomeOlderClass olderClass = new SomeOlderClass(myClass);
I have an interface (SomeInterface) that several classes call into (such as SomeOlderClass). I have a class that implements the interface, but I want to do type safe operations on the specific implementations that are passed into the generic interface.
As shown in the above code, I really want to able to make another method that matches the specific type passed in to the interface. This doesn't work. I assume it is because the calling code only knows about the interface, and not the implementation with the more specific methods (even though SpecificFoo implements Foo)
So how can I do this in the most elegant way? I can get the code working by adding an if statement in the class implementing the interface (SomeClass):
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
if ( someKindOfFoo.getClass().equals(SpecificFoo.class) )
thisMethod(SpecificFoo.class.cast(someKindOfFoo));
else
System.out.println("Dont go here please");
}
However, this is not elegant, as I have to add if statements everytime I add a new kind of Foo. And I might forget to do so.
The other option is to add SpecificFoo to the SomeInterface, and let the compiler sort out reminding me that I need implementations in SomeClass. The problem with this is that I end up adding quite a bit of boiler plate code. (If someone else implements the interface, they have to implement the new method, as well as any tests)
It seems that there should be another option I am missing, given that Foo and SpecificFoo are related. Ideas?
MORE INFO:
Well I actually worked for a while to try and simplify the question. As I add more details the complexity goes up by quite a bit. But whatever... I think I can explain it.
Basically, I am write a GWT web apps RPC servlet using the command pattern as explained by Ray Ryan in his talk
There are several implementations of it on google code, but many of them suffer this inherit problem. I thought it was a bug in the GWT-RPC code bugreport HOWEVER, as I was implementing further I noticed a similar problem happening purely on the client side, and while in hosted mode. (ie all java, no gwt javascript madness).
So I abstracted the basic ideas to a raw java command line case, and saw the same issue, as described above.
If you follow along with what Ray Ryan discusses, Foo is an Action, SpecificFoo is a specific action I want to call. SomeInterface is the client side RPC service and SomeClass is the server side RPC class. SomeOlderClass is a kind of rpc service that would know about cacheing and whatnot.
Obvious, right? Well as I said, I think all the GWT RPC nonsense just muddies up the waters on the base issue, which is why I tried to simplify it as best I could.
If you need to find out the actual type of an object at runtime, then the design is most probably wrong. That violates at least the Open Closed Principle and Dependency Inversion Principle.
(Because Java does not have multiple dispatch, the thisMethod(Foo)will be called instead of thisMethod(SpecificFoo). Double dispatch could be used to get around the language's limitations, but there might still be some design problem lurking there...)
Please give more information on what you are trying to accomplish. Right now the question does not provide enough information to come up with a right design.
A generic solution is that since the action depends on the runtime type of Foo, that method should be part of Foo so that its implementation can vary depending on Foo's type. So your example would be changed to something like below (possibly adding SomeInterface or other parameters to thisMethod()).
public interface Foo {
void thisMethod();
}
public class SpecificFoo implements Foo {
public void thisMethod() {
System.out.println("Go here please");
}
}
Try using double dispatch: Add a method to the Foo interface that is called by SomeClass#thisMethod. Then place the code in the implementation of this method.
public interface Foo {
public void thatMethod(SomeClass a);
public void thatMethod(SomeOlderClass a);
}
public class SomeClass implements SomeInterface {
public void thisMethod(Foo someKindOfFoo) {
someKindOfFoo.thatMethod(this);
}
}
Sorry, I find the problem description far too abstract to be able to make a recommendation. You clearly have a design issue because you generally should not need to check the type of interface. I will give it a go though... First, I need to make your problem more concrete for my small brain to understand. Instead of Foos, how about Birds?
public interface Bird {
}
public class Ostrich implements Bird {
}
public interface BirdManager {
void fly(Bird bird);
}
public class AdvancedBirdManager implements BirdManager {
public void fly(Bird bird) {
System.out.println("I am in the air. Yay!");
}
public void fly(Ostrich ostrich) {
System.out.println("Sigh... I can't fly.");
}
}
public class ZooSimulation {
public ZooSimulation(BirdManager birdManager) {
Ostrich ostrich = new Ostrich();
birdManager.fly(ostrich);
}
}
public static void main(String[] args) {
AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
Here, the Ostrich will declare "I am in the air. Yay!" which is not what we want.
OK, so, ignoring the fact that I am failing basic OO here, the problem is that the BirdManager will look for the least-specific method that matches the type that is passed in. So no matter what kind of bird I give it, it will always match fly(Bird). We can put some if checks in there, but as you add more types of birds, your design will degrade further. Here's the tough part - I have no idea if this makes sense within the context of your problem, but consider this refactoring where I move the logic from the manager into bird:
public interface Bird {
void fly();
}
public class BasicBird implements Bird {
public void fly() {
System.out.println("I am in the air. Yay!");
}
}
public class Ostrich implements Bird {
public void fly() {
System.out.println("Sigh... I can't fly.");
}
}
public interface BirdManager {
void fly(Bird bird);
}
public class AdvancedBirdManager implements BirdManager {
public void fly(Bird bird) {
bird.fly();
}
}
public class ZooSimulation {
public ZooSimulation(BirdManager birdManager) {
Ostrich ostrich = new Ostrich();
birdManager.fly(ostrich);
}
}
public static void main(String[] args) {
AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
Our Ostrich now says the correct thing and the bird manager still treats it as just a bird. Again, bad OO (Ostriches should not have fly() methods) but it illustrates my thoughts.
As long as there are not too many implementations of Foo, I would declare an abstract method in SomeInterface for each subclass of Foo, and have an abstract class forward calls to a default method that is defined for the most general type:
public interface Foo {
}
public class SpecificFoo implements Foo {
}
public interface SomeInterface {
void thisMethod(Foo someKindOfFoo);
void thisMethod(SpecificFoo specificFoo);
void thisMethod(OtherSpecificFoo otherSpecificFoo);
}
public abstract class AbstractSomeInterface {
public void thisMethod(Foo wrongFoo) {
throw new IllegalArgumentException("Wrong kind of Foo!");
}
public void thisMethod(SpecificFoo specificFoo) {
this.thisMethod((Foo) specificFoo);
}
public void thisMethod(OtherSpecificFoo otherSpecificFoo) {
this.thisMethod((Foo) specificFoo);
}
}
public class SomeClass extends AbstractSomeInterface {
public void thisMethod(SpecificFoo specificFoo) {
// calling code goes into this function
System.out.println("Go here please");
}
}
public class SomeOlderClass {
public SomeOlderClass( SomeInterface inInterface ) {
SpecificFoo myFoo = new SpecificFoo();
inInterface.thisMethod(myFoo);
}
}