Does java support "Soft" interfaces? - java

Consider the following scenario:
Say that you created an interface Foo:
public interface Foo {
public void bar();
}
And say that there is an old class SomeOldClass in a certain library that you want to use. It already has the bar() method, but does not explicitly implement Foo.
You have written the following code for all classed that implement Foo:
public <T extends Foo> T callBarOnThird(List<T> fooList){
return fooList.get(2).bar();
}
And now you want it to also work for SomeOldClass. You dont have access to the source code of this class, so you can't modify it.
Is there a way to declare Foo or something similar as some sort of "soft" interface, (as in where any class that implements all the required methods would be accepted as an implicit implementation of the soft interface)? If not, how would you solve this with code that is as clean as possible?

No, it does not.
You have to provide an adapter instance (there are several methods and tools to help with that, but Java does not do it "implicitly").

Java is statically typed and dynamically bind.
Dynamically bind: This means that the linking between a method signature and its implementation happens at runtime. For example.
For example
public interface MyInterface {
void doStuff();
}
public class MyFirstImpl implements MyInterface {
#Override
public void doStuff() {
// do some stuff here
}
}
public class MySecondImpl implements MyInterface {
#Override
public void doStuff() {
// do some stuff here
}
}
So if you would have the next snippet
MyInterface test; // pointing to either MyFirstImpl or MySecondImpl
test.doStuff();
The JVM will determine at runtime weather to call the doStuff method from MyFirstImpl or MySecondImpl based on the runtime type of the object.
Statically typed: This means that the JVM will check at compile time weather a there is a method to call regardless of the implementation.
For example:
public interface MyInterface {
void doStuff();
}
public class MyFirstImpl implements MyInterface {
// no override here
public void doStuff() {
// do some stuff here
}
}
public class MySecondImpl implements MyInterface {
// no override here
public void doStuff() {
// do some stuff here
}
}
So if you would have the next snippet
MyInterface test; // pointing to either MyFirstImpl or MySecondImpl
test.doStuff();
The compiler will complain because it can't ensure at compile time that regardless of the implementation of MyInterface there is a doStuff method to call (although in this case, both implementations of MyInterface define a doStuff method).
This ensures that you won't get a NoSuchMethodException at runtime, if you would pass, for example, the next implementation.
public class MySecondImpl implements MyInterface {
// no override here
// no doStuff method
}
This adds some type safety to the language at the cost of some rigidity (since you are able to determine the issue earlier than at runtime and therefore you have a shorter feedback loop, at the cost of the scenario in which all the implementations actually expose the method not working out of the box).
How you should refactor your code:
Create a wrapper over the third party library and expose the interface from the wrapper.
public interface Foo {
void bar();
}
public class ThirdPartyFooWrapper implements Foo {
private SomeOldClass oldClass;
public ThordPartyFooWrapper (SomeOldClass oldClass){
this.oldClass = oldClass;
}
#Override
public void bar() {
this.oldClass.bar();
}
}
Then, in your code use ThirdPartyFooWrapper instead of SomeOldClass.
Hope this answers your question!

Extension to Thilos answer.
You can also use the decorator to handle this
public <T extends Foo> T callBarOnThird(List<T> fooList){
return new BarDecorator(fooList.get(2)).bar();
}
Inside the decorator, you can check if given Object is the instance of Foo or not then do operations accordingly.

Related

When I extend an interface A with interface B, will A's methods be available for free to B's implementors?

I'm curious how this all works. I have an interface, let's call it A. When I look at A, it has most of the methods I need, but not all, and I don't have control over interface A, so I extend it with interface B which implements the 1 or whatever number of methods that I need on top of A.
public interface B extends A {
String doSomethingFun(String blah);
}
A has an implementation class called Client. In just a second I'm going to create my own implementation class of B called MyDefaultClient.
I then create a concrete class that implements B, like this:
#Component
public class MyDefaultClient implements B {
private A myClient;
#Autowired
public MyDefaultClient(A myClient) {
this.myClient = myClient;
}
#Override
public String doSomethingFun(String filename) {
// custom business logic
}
#Override
public String serviceName() {
return myClient.serviceName();
}
#Override
public void close() {
myClient.close();
}
}
serviceName() and close() are methods that A forces its implementors to implement. There are other methods though that have default implementations that aren't forcing me to implement them, I assume simply because they have default implementations.
At this point I have a concrete class that I can instantiate in other places and call all of both A and B's methods on it. But is that only because in the interface there are default implementations for these methods, like this?
default Blah someMethodInA(String thing) {
throw new UnsupportedOperationException();
}
If I use this code and call myDefaultClient.doSomethingFun("hello") I'm pretty certain that will do the thing I want it to do. But what about if I call myDefaultClient.someMethodInA()? Will it call the implemented method in Client, which is A's implementor? Or will it fall on the floor and complain with an UnsupportedOperationException? If the latter, is there any way I can structure this so that I can call all of A's methods from B's implementor?
If you want MyDefaultClient to inherit implementations from Client, then it has to extend Client, like this:
class MyDefaultClient extends Client implements B
{
...
}
Then, if Client implements A, you will only have to provide implementations for the new methods that B adds.
or... you can continue your current pattern and explicitly delegate all the calls you want to a field of type A, but you will have to do them all explicitly, even the methods with default implementations. The default implementations will continue the throw exceptions if you don't override them.
An interface can have any number of default methods. Check this for more details. Given below is an example to demonstrate how default methods and extending an interface work:
public interface InterfaceA {
public void toBeImplementedA();
default void hello() {
System.out.println("Hello");
}
default void hi() {
System.out.println("Hi");
}
}
public interface InterfaceB extends InterfaceA {
public void toBeImplementedB();
}
public class AnImplClass implements InterfaceB {
#Override
public void toBeImplementedA() {
System.out.println("toBeImplementedA");
}
#Override
public void toBeImplementedB() {
System.out.println("toBeImplementedB");
}
}
public class Main {
public static void main(String[] args) {
InterfaceB obj = new AnImplClass();
obj.toBeImplementedA();
obj.toBeImplementedB();
obj.hello();
obj.hi();
}
}
Output:
toBeImplementedA
toBeImplementedB
Hello
Hi
Feel free to comment in case of any doubt.
Interfaces can contain default methods. These were added to Java so that an interface could be updated without forcing implementing code to be rewritten.¹
Default methods provide an implementation if your implementing class does not implement them.
When you call methods on an object, the overridden method is always called.
Any other implementations in the super classes / interfaces are used when there is a lack of implementation.
Even if you refer to MyDefaultClient as A,
A myImplementation = new MyDefaultClient();
Under the hood myImplementation is still an instance of MyDefaultClient even though the code views it as A. Therefore your overriden method will be used when doSomethingFun is called.
#Override
public String doSomethingFun(String filename) {
// custom business logic
}
¹ Source: https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

How to protect a method implementing an interface from overriding?

I have interface:
public interface Doable {
void doSomething();
}
and the class that implements it:
public class DoJump() implements Doable {
#Override
private void doSomething() {
fireJumpHandler();
}
}
This is stupid example, but I would like to present the problem.
This code doesn't compile, I am getting an error in Eclipse IDE:
Cannot reduce the visibility of the inherited method from
Doable
I have common interface that declares a method. This method is overriden in concrete class. I would like to avoid another class that can extend this class (DoJump), so I would like to hide this method from sub classes. I would like to use private modifier, but Java does not allow me to do it.
Why it is impossible, and how to workaround it?
I'd like to answer your last question "How to workaround it?" as this is not described in the related question. Create a second interface NotDoable which simply does not have doSomething() declared. Then let your DoJump implement both interfaces. Give everyone that shouldn't override doSomething a reference to the interface NotDoable instead of the true type DoJump. Then they won't know that the object truly can doSomething, they won't know per class design. Of course, one can workaround this but one actually can workaround everything. The class design is more correct this way. Here's some code:
public interface Doable {
public void doSomething();
}
public interface NotDoable {
}
public class DoJump implements Doable, NotDoable {
#Override
public void doSomething() {
System.out.println("hi");
}
public NotDoable meAsNotDoable() {
return this;
}
public static void main(String[] args) {
DoJump object = new DoJump();
// This call is possible, no errors
object.doSomething();
NotDoable hidden = object.meAsNotDoable();
// Not possible, compile error, the true type is hidden!
hidden.doSomething();
}
}
But as said, one can workaround this by using if (hidden instanceof DoJump) { DoJump trueObject = (DoJump) hidden; }. But well, one can also access private values via reflection.
Other classes now implement NotDoable instead of extending DoJump. If you declare everything others should know about DoJump in this interface, then they only can do what they should do. You may call this interface IDoJump and the implementing class DoJump, a common pattern.
Now the same a bit more concrete.
public interface IDog {
public void bark();
}
public interface ICanFly {
public void fly();
}
public class FlyingDog implements IDog, ICanFly {
#Override
public void bark() {
System.out.println("wuff");
}
#Override
public void fly() {
System.out.println("Whuiiii");
}
public static void main(String[] args) {
FlyingDog flyingDog = new FlyingDog();
// Both works
flyingDog.fly();
flyingDog.bark();
IDog dog = (IDog) flyingDog;
// Same object but does not work, compile error
dog.fly();
ICanFly canFly = (ICanFly) flyingDog;
// Same object but does not work, compile error
canFly.bark();
}
}
And now an extending class.
public class LoudDog implements IDog {
#Override
public void bark() {
System.out.println("WUUUUFF");
}
// Does not work, compile error as IDog does not declare this method
#Override
public void fly() {
System.out.println("I wanna fly :(");
}
}
In the end, be aware that if others know that their IDog actually is a FlyingDog (and they cast it), then they must be able to call fly() as a FlyingDog must can fly. Furthermore, they must be able to override the behavior as long as they follow the specification of fly() given by its method-signature. Imagine a subclass called PoorFlyingDog, he needs to override the default behavior, else he can perfectly fly, but he is a poor flyer.
Summarized: Hide to others that you're actually a DoJump, also hide that you are a Doable, pretend to only be a NotDoable. Or with the animals, pretend to only be an IDog instead of a FlyingDog or ICanFly. If the others don't cheat (casting), they won't be able to use fly() on you, though you actually can fly.
Add final to DoJump declaration to prevent this class to be overriden (and therefore doSomething() to be overriden too).
public final class DoJump implements Doable {
#Override
public void doSomething() {
fireJumpHandler();
}
}
If you still need to be able to inherit DoJump but you don't want doSomething() to be overriden, put the final modifier in the method signature
public class DoJump implements Doable {
#Override
public final void doSomething() {
fireJumpHandler();
}
}

Java: method only callable by superclass

I would like to prevent a class from calling its own method. The method shall only be callable by its super class.
Right now, I cannot think of any way to achieve this (cleanly). But maybe someone knows a solution?
In code:
public abstract class A {
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
public class B extends A {
#Override
protected void foo() {
//do smth
}
private void barB() {
//must not be able to call foo() here
}
}
Edit: the explanation why I would like to do this:
A is lets say a vehicle. B can be a car or an airplane. The method foo() would be startEngines(). -> I want to make sure that the engines can only be started by calling the method barA().... does that make any sense?
There is a way to do it, but you need to use Google Error Prone. This is an extension of the Java compiler that aims to provide more and more helpful warnings and errors (similar to FindBugs and PMD, but with less false alarms). I can only recommend it, it has already helped us to find some bugs.
Specifically, it contains an annotation #ForOverride and an according compile-time check. This annotation is meant to be used for protected methods that the sub-class and any other class should not call, but only the defining class.
So using
public abstract class A {
#ForOverride
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
would exactly achieve what you want.
You can integrate Error Prone into most build systems like Maven and Ant. Of course, it won't help if somebody compiles your source without Error Prone (for example in Eclipse), but using it in a continous-integration system would still allow you to find such issues. The source code still stays compatible with regular Java compilers (provided you have error_prone_annotations.jar on the class path), other compilers will simply not do the additional checks.
this answer has a good hint.
add below method in your class (class B):
public static String getMethodName(final int depth)
{
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
return ste[ste.length - 1 - depth].getMethodName();
}
and change the foo method in class B to this:
#Override
protected void foo() {
//....
if (getMethodName(0)=="barB"){
// tell you are not able to call barB
}
}
Considering your vehicle and engine scenario, I think you need to reconsider your design a bit.
Your vehicle could be a car, aeroplane, etc but car, aeroplane, ... each have separate engines and therefore different startEngine method. So declare your class vehicle as abstract like you did and class startEngine as abstract method . Next , subclass Vehicle and implement startEngine in them , now you can invoke startEngine on the subclass instances
abstract class Vehicle{
abstract void startEngine();
}
public class Car extends Vehicle{
public void startEngine(){
//implementation
}
public static void main(String[] arg){
Vehicle v=new Car();
v.startEngine();
}
}
Add Anonymouse inner class to barA method via Interface, so you will need to implement a method for foo() (functional interface). It won't be part of Class B.
you could put an interface as a member in the super class given to it via the constructor. the child class implements the method but can't call it except by making it static.
interface Foo {
void stopEngines();
void startEngines();
}
abstract class Base {
final private Foo foo;
public Base(final Foo foo) {
this.foo = foo;
}
private void barA() {
// do smth
foo.startEngines();
}
}
class Child extends Base {
public Child() {
super(new Foo() {
boolean engineRunning;
#Override
public void stopEngines() {
this.engineRunning = false;
}
#Override
public void startEngines() {
this.engineRunning = true;
}
});
}
private void barB() {
// can't call startEngines() or stopEngines() here
}
}
class Child2 extends Base {
public Child2() {
super(new Foo() {
#Override
public void stopEngines() {
stopEngines();
}
#Override
public void startEngines() {
startEngines();
}
});
}
static void stopEngines() {
// influence some static state?
}
static void startEngines() {
// influence some static state?
}
private void barB() {
// can call stopEngines() and startEngines(), but at least they have to be static
}
}
Of course, this is not really what you asked for, but about as much as you can do about it in Java, I guess.
Seeing the startEngines explanation, this solution might even suffice.
I guess you wouldn't care about the class calling its static methods, since they can only influence a static state, which is used seldom. The methods within the anonymous interface implementation can mutually call each other, but I guess that would be OK, since you only seem to be trying to prevent others to start the engines in some different way.
I guess this is similar to the problem AWT/Swing has with overriding the paint(Graphics g) method on a component (or onCreate(..) in Android Activities). Here you are overriding the paint method but you should never call it.
I think the best thing you can do is add documentation to the method to clarify that it should never be explicitly called by the subclasses OR re-evaluate your design.

Can I tell if an abstract method has been called?

Given this class:
abstract class Foo{
public Foo(){...}
public abstract void checkable();
public void calledWhenCheckableIsCalled(){
System.out.println("checkable was called");
}
}
Is there any code I can put in Foo's constructor to make calledWhenCheckableIsCalled get called when checkable is called?
Note: This is a gross simplification of an actual project I am working on.
Edit: I have already implemented a template pattern workaround. I just wondered if there was another way to do this I am missing. (Perhaps using reflection.)
Looks like a template method pattern.
But then you must implement Foo.checkable() and introduce another abstract method to delegate to.
abstract class Foo{
public Foo(){}
public void checkable(){
calledWhenCheckableIsCalled();
doCheckable();
}
protected abstract void doCheckable();
public void calledWhenCheckableIsCalled(){
System.out.println("checkable was called");
}
}
I would also suggest to make checkable() final in this case so that you can be sure that checkable() can not implemented in another way as you expected.
In addition to Brian Roach's comment
The downside is that the protected can be expanded to public in the subclass, so you can't explicitly enforce it.
That's true, but you can prevent a Foo instance from being instantiated if a subclass increases the visibility of doCheckable. Therefore you have to introduce a verification whenever an object is instantiated. I would recommend to use an initializer code so that the verification is executed on every constructor that exists. Then it can not be forgotten to invoke and therefore be by-passed.
For example:
abstract class Foo {
{ // instance initializer code ensures that enforceDoCheckableVisibility
// is invoked for every constructor
enforceDoCheckableVisibility();
}
public Foo() {...}
public Foo(Object o) {...}
private void enforceDoCheckableVisibility() {
Class<?> currentClass = getClass();
while (currentClass != Foo.class) {
try {
Method doCheckableMethod = currentClass.getDeclaredMethod("doCheckable");
if (Modifier.isPublic(doCheckableMethod.getModifiers())) {
throw new RuntimeException("Visibility of "
+ currentClass.getSimpleName()
+ ".doCheckable() must not be public");
}
} catch (SecurityException | NoSuchMethodException e) {}
currentClass = currentClass.getSuperclass();
}
}
}
Since the check is implemented using reflection the downside is that it is only checked at runtime. So you will not have compiler support of course. But this approach let you enforce that an instance of a Foo can only exist if it fulfills your contract.
No, the constructor will get invoked once during the object initialisation. You can however get your subclass that provides the implementation to call the method in the super class:
class Bar extends Foo {
// implementation of abstract method
public void checkable(){
super.calledWhenCheckableIsCalled(); // call to parent's method
...
}
}
EDIT
You could achieve this with aspects. Using an aspect you can intercept each call to a method by referring to the abstract parent method. This leaves you free from interfering eith the child code. Your calledWhenCheckableIsCalled code would then become part of the intercepting code.
abstract class Foo {
// use pointcut to intercept here
public void checkable();
}
There is no way as you are forcing that method to implement in child.
An awkward suggestion will be know from child implementation. I mean there is no clean way AFAIK
abstract class foo {
public abstract void bar();
public void moo() {
System.out.println("some code");
this.bar();
System.out.println("more code");
}
}
now if moo is called, the underlying implementation of bar will be used, it is just a small paradigm shift from what you want.
so your end user would call moo instead of bar, but he still needs to implement bar
Nope, an abstract method doesn't have a body. You could, however, chain your method like this:
abstract class Foo {
void callMeInstead() {
// do common
callMeImplementation();
}
abstract void callMeImplementation();
}
It looks to me like you're looking for the template pattern:
public abstract class Template {
public final void checkable() {
calledWhenCheckableIsCalled();
doCheckable();
}
protected abstract void doCheckable();
private void calledWhenCheckableIsCalled() {
System.out.println("checkable was called");
}
}
Now, each time checkable() is called, calledWhenCheckableIsCalled() is also called. And the suclass must still provide the actual implementation of checkable(), by implementing the doCheckable() method.
Note that making checkable() final prevents a subclass from overriding it and thus bypassing the call to calledWhenCheckableIsCalled().

How to use java interfaces with multiple implementing classes

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);
}
}

Categories

Resources