abstract class A {
int met(A a) {
return 0;
}
int met(B b) {
return 1;
}
int met(C c) {
return 2;
}
}
class B extends A {
int met(A a) {
return 3;
}
int met(B b) {
return 4;
}
int met(C c) {
return 5;
}
}
class C extends B {
int f() {
return ((A)this).met((A)this);
}
}
public class teste {
public static void main(String args[]) {
C x = new C();
System.out.println(x.f());
}
}
The program will return 3 and I was expecting 0. Why does the first cast in the method f do nothing and the second one works? Is it because in the A and B classes the met methods are overloaded and therefore static binding is used?
That's just the way polymorphism works. Just consider this example:
A a = new C();
a.met(a);
This would as expected call the correct method B#met(...). The method-tables for an object don't just change because you change the type of the variable you stored the Object in, since the binding between an Object and it's methods is stronger than the one between the storage-type and the methods related to it. The second type works, because the type of the input is casted to A and thus the method recognizes it as A (the type of the input-storage has stronger binding than the Object type).
Trying to pass a java test I faced the following question
class A {
int f() { return 1; }
}
class B extends A {
int f() { return 2; }
}
class C extends B {
int f() { return 3; }
int test() {
return super.f() +
((A)this).f();
}
}
Can't figure out why ((A)this).f() returns 3 but not 1?
This is dynamic dispatch, the static type of the object ((A)this, which is A) does not matter, only the dynamic type, and that is C.
Similarly, if you do
A a = this;
a.f();
The same value (3) will be returned.
I have an abstract class X and some classes who extend this class, call them A, B and C.
In some other class Y I have a few methodcalls that depend on the type of the class. The if-else statement looks like this:
public class Y implements InterfaceY {
public Y(){
}
public String doStuff (X x, Boolean flag) {
String s = "";
if (x instanceof A) {
doStuff((A) x));
} else if (x instanceof B) {
doStuff((B) x));
} else if (x instanceof C) {
doStuff((C) x, flag);
} else {
throw new Exeption();
}
return s;
private String doStuff(A a) {
return "";
}
private String doStuff(B b) {
return "";
}
private String doStuff(C c, Boolean flag) {
return "";
}
}
Note that all methods have the same name (doStuff()) but depending on the class (and sometimes flag) call a different method implementation of that method. Of course this looks horrible and gets immensely complicated once the classed that are extended from X increase.
Is there any way that I can somehow create an intermediate Interface that (or something else) that takes care of the majority (or all) of the if-else statements?
First take these methods out of here, and put them in the A, B and C class respectively, implementing the X interface.
private String doStuff(A a) {
return "";
}
private String doStuff(B b) {
return "";
}
private String doStuff(C c, Boolean flag) {
return "";
}
Then:
if (x instanceof A) {
doStuff((A) x));
} else if (x instanceof B) {
doStuff((B) x));
} else if (x instanceof C) {
doStuff((C) x, flag);
can just be x.doStuff(); (you don't even have to pass the A, B, C because that will be this inside the method. The flag you'll have to mess around with depending more specifically on your code. for example, the other 2 doStuff methods could accept the flag as well, but just ignore it)
What about implementing a Handler interface then map it by supported type:
public interface Handler<T extends X>{
Class<T> supportedClass;
void doStuff(T value, Object...args);
}
public class Y implements InterfaceY {
private Map<Class<?>, Handler<?>> handlers;
public Y(List<Handler<?>> handlers){
// populate map
}
public void process(X value){
handler.get(value.getClass).doStuff(X, ...);
// you would have to figure out how to determine when other values are needed
}
}
What about some double dispatch?
class X {
public String letYdoStuff(Y y, Boolean flag) {
return y.doStuff(this, flag);
}
public static void main(String [] args) {
//X x = new A();
X x = new B();
Y y = new Y();
y.doStuff(x, false);
}
public X getThis() {
return this;
}
}
class A extends X {
public String letYdoStuff(Y y, Boolean flag) {
return y.doStuff(this, flag);
}
}
class B extends X {
public String letYdoStuff(Y y, Boolean flag) {
return y.doStuff(this, flag);
}
}
class C extends X {
public String letYdoStuff(Y y, Boolean flag) {
return y.doStuff(this, flag);
}
}
class Y {
public Y(){
}
public String doStuff (X x, Boolean flag) {
String s = "";
return x.letYdoStuff(this, flag);
}
public String doStuff(A a, Boolean flag) {
System.out.println("in A");
return "";
}
public String doStuff(B b, Boolean flag) {
System.out.println("in B");
return "";
}
public String doStuff(C c, Boolean flag) {
System.out.println("in C");
return "";
}
}
APPROACH 1
Use the state pattern. It takes care of your problem and eliminates the ifs and elses.
Here is the java example.
The state pattern delegates the methods calls to objects that implement the same interface but with different behaviour.
State pattern example:
public class StatePatternExample {
public static void main(String[] args) {
Girlfriend anna = new Girlfriend();
// OUTPUT
anna.kiss(); // *happy*
anna.greet(); // Hey, honey!
anna.provoke(); // :#
anna.greet(); // Leave me alone!
anna.kiss(); // ...
anna.greet(); // Hey, honey!
}
}
interface GirlfriendInteraction extends GirlfriendMood {
public void changeMood(GirlfriendMood mood);
}
class Girlfriend implements GirlfriendInteraction {
private GirlfriendMood mood = new Normal(this);
public void provoke() {
mood.provoke();
}
public void kiss() {
mood.kiss();
}
public void greet() {
mood.greet();
}
public void changeMood(GirlfriendMood mood) {
this.mood = mood;
}
}
interface GirlfriendMood {
public void provoke();
public void kiss();
public void greet();
}
class Angry implements GirlfriendMood {
private final GirlfriendInteraction context;
Angry(GirlfriendInteraction context) { // more parameters, flags, etc. possible
this.context = context;
}
public void provoke() {
System.out.println("I hate you!");
}
public void kiss() {
System.out.println("...");
context.changeMood(new Normal(context));
}
public void greet() {
System.out.println("Leave me alone!");
}
}
class Normal implements GirlfriendMood {
private final GirlfriendInteraction context;
Normal(GirlfriendInteraction context) {
this.context = context;
}
public void provoke() {
System.out.println(":#");
context.changeMood(new Angry(context));
}
public void kiss() {
System.out.println("*happy*");
}
public void greet() {
System.out.println("Hey, honey!");
}
}
As you can see, the class Girlfriend has no ifs and elses. It looks pretty clean.
The class Girlfriend corresponds to your abstract class X, the classes Normal and Angry correspond to A, B and C.
Your class Y then directly delegates to X without checking any cases.
APPROACH 2
Use the command pattern. You could then hand over a command object to Ys doStuff() method and just execute it.
This can be a difficult problem. I think Cruncher's solution, add
doStuff to X and override it in A, B, C, is the simplest and
best solution when it's appropriate. However, it isn't always
appropriate, because of the Single responsibility
principle.
(I think that's the correct term. My apologies if I get some
terminology wrong, I'm not entirely up-to-date on all of the terms.)
The idea is that you shouldn't necessarily doStuff to X if it has
nothing to do with the purpose of X. If X and Y are part of the
same "team", i.e. they've been both set up to serve the purpose of one
particular application, then it's probably OK.
But suppose you have an abstract Shape class that has subclasses
Circle, Square, Undecagon, RandomBlob, etc. There will be
some methods that belong in the Shape class that would be useful to
any application that uses the Shape class. But now say you are
writing a game that uses some of those shapes, and you want a
polymorphic operation that determines what happens when the shape gets
eaten by a flying monkey. You wouldn't want to add an abstract
computeEatenByFlyingMonkey method to your Shape class, even if the
class were your own creation and not in someone else's library,
because that would be just too specific for a class that could be
generally used for other purposes than this one game.
I can think of a couple ways to approach this.
If it's not appropriate (or not possible) to add doStuff to X, but
if A, B, and C are more closely connected to your application so
that adding doStuff to them is appropriate, you can add another
class:
public abstract class XWithStuff extends X {
// repeat any constructors in X, making them all be just
// calls to super(...)
public abstract void doStuff (Boolean flag);
}
public class A extends XWithStuff {
#Override
public void doStuff (Boolean flag) { ... }
}
and so on for every other class. (XWithStuff is just an example
name; in real life, a name that contains both "X" and some reference
to the application or purpose is probably better.) (P.S. I don't know
why you're using Boolean instead of boolean but I'm leaving it
that way in case there's a good reason.)
If it's also not appropriate or not possible to add doStuff to A,
B, and C, here's a possible solution:
public interface StuffInterface {
public void doStuff (Boolean flag);
}
public class AWithStuff extends A implements StuffInterface {
#Override
public void doStuff (Boolean flag) { ... }
}
and then in your program create objects of class AWithStuff instead
of A, etc. To call doStuff on an X:
void doStuff (X x, Boolean flag) {
if (x instanceof StuffInterface) {
((StuffInterface) x).doStuff (flag);
} else {
throw new IllegalArgumentException ();
}
}
If that's not an option and you have to deal directly with A, B,
etc., and you can't add doStuff to those classes, then any solution
will be a bit hacky. If you don't want to use if-then-else, you
could look into the visitor pattern, or you could conceivably create
a HashMap<Class<?>,Interf> that would map A.class, B.class,
etc., to some interface object that calls the correct doStuff. But
I haven't worked out the details. (Actually, the "visitor pattern" probably wouldn't be appropriate unless you have some sort of complex structure composed of objects of type X.)
Separate a DoStuffOperation, create the relative factory and use them.
public interface DoStuffOperation<T> {
String doStuff(T x);
}
public class ADoStuffImpl implements DoStuffOperation<A> {
public String doStuff(A x) {
return "doStuff<A>";
}
}
public class ADoStuffWithFlagImpl implements DoStuffOperation<A> {
public String doStuff(A x) {
return "doStuffWithFlag<A>";
}
}
public class DoStuffImplFactory {
public final static <T extends X> DoStuffOperation<X> getDoStuff(Class<T> xClass,boolean flag) {
DoStuffOperation<X> impl = null;
if(xClass.equals(A.class))
{
if(flag)
impl = (DoStuffOperation)new ADoStuffWithFlagImpl();
else
impl = (DoStuffOperation)new ADoStuffImpl();
}
}
return impl;
}
}
public class Y implements InterfaceY {
public String doStuff (X x, Boolean flag) {
return DoStuffImplFactory.getDoStuff(x.getClass(),flag).doStuff(x);
}
}
In this way you don't have to refactor call to Y.doStuff() or X and derived classes.
You can't remove at all some sort of instanceof to decide which implementation of doStuff() use unless X classes implements a DoStuffCreator interface like:
interface DoStuffCreator {
DoStuffOperation getDoStuffOperation(boolean flag);
}
X and A are your classes. You can also construct using reflection or other automatic way (external property file and so on).
The situation:
I have a class hierarchy that looks a little bit like this. Note, my doesn't really look like this, I just wrote it this way to make it shorter and, in my opinion, more legible.
public abstract BaseClass {
private Alpha a;
private Beta b;
public Alpha getAlpha() { return a; }
public Beta getBeta() { return b; }
public BaseClass setAlpha(Alpha a) { this.a = a; return this; }
public BaseClass setBeta(Beta b) { this.b = b; return this; }
}
public Foo extends BaseClass {
#Override
public Foo setBeta(Beta b) {
super.setBeta(b);
doSomethingElse();
return this;
}
public Gamma getGamma() { return g; }
public Foo setGamma(Gamma g) { this.g = g; return this; }
}
public Bar extends BaseClass {
private Omega o;
#Override
public Bar setAlpha(Alpha a) {
super.setAlpha();
doSomethingElse();
return this;
}
public Omega getOmega() { return o; }
public Bar setOmega(Omega o) { this.o = o; return this; }
}
The problem:
There are many more of these methods then listed above. Notice that they don't conform to the same interface. The classes that use Foo and Bar and need to call setGamma and setOmega always have access to the most specific class. However, those same classes also need to call setAlpha and setBeta. Those methods don't return the correct type, however, unless I override them.
Options:
Override every method of BaseClass just to change the return type
Seems a lot of unnecessary code
Declare every method like setGamma and setOmega abstract in BaseClass. This might work, except then I'd have to define it for classes where it really makes no sense at all.
Similar to #2, except I don't declare these methods abstract, I give them an implementation - throw new UnsupportedOperationException()
Similar to #3, except I just ignore the problem rather than throwing an Exception.
Always all my builders with the most specific return types first. i.e. someBar.setOmega().setAlpha() but not someBar.setAlpha().setOmega()
All of these options seem gross. Does anyone have anything better?
Note: this situation is not quite like this one: Java - Inherited Fluent method return type to return incident class' type, not parent's as it's not really a generics issue.
As #chrylis noted in the comments, you can genericize BaseClass:
public abstract class BaseClass<T extends BaseClass> {
private Alpha a;
private Beta b;
public Alpha getAlpha() {
return a;
}
public Beta getBeta() {
return b;
}
#SuppressWarnings("unchecked")
public T setAlpha(Alpha a) {
this.a = a;
return (T) this;
}
#SuppressWarnings("unchecked")
public T setBeta(Beta b) {
this.b = b;
return (T) this;
}
}
and extend as follows:
Foo:
public class Foo extends BaseClass<Foo> {
private Gamma g;
#Override
public Foo setBeta(Beta b) {
super.setBeta(b);
doSomethingElse();
return this;
}
private void doSomethingElse() { }
public Gamma getGamma() {
return g;
}
public Foo setGamma(Gamma g) {
this.g = g;
return this;
}
}
Bar:
public class Bar extends BaseClass<Bar> {
private Omega o;
#Override
public Bar setAlpha(Alpha a) {
super.setAlpha(a);
doSomethingElse();
return this;
}
private void doSomethingElse() { }
public Omega getOmega() {
return o;
}
public Bar setOmega(Omega o) {
this.o = o;
return this;
}
}
This introduces a couple unchecked cast warnings, which I suppressed. It compiles, but I haven't tried actually doing anything with it.
I've been dealing with a domain issue where I have classes that implement a common interface and I want to be able to get hashes from these objects differently depending on if the object is accessed as an interface or as a concrete class instance. Basically what I want is the following:
public class A implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int Bar.hashCode(){ return 123;}
}
public class B implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int Bar.hashCode(){ return 123;}
}
public class C implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int Bar.hashCode(){ return 123;}
}
Bar interfaceObject = new A();
interfaceObject.hashCode(); //return 123
Bar aObject = new A();
aObject.hashCode();// return 1
As far as I know there isn't a way to do this, and I can think of lots of reasons why this could cause issues, but I wanted to ask those smarter than I if they had any nice ways of doing this outside of making the interface have a function like public int getCustomHashCodeForJustThisInterface(). I like being able to use these objects in hashMaps without having to jump through hoops, but with their current implementation of hashCode they would break, since these objects can have multiple views of their identity depending on how they are used, and I don't want to change their base implementation of hashCode;
You can't do that, because Java does not support non-polymorphic instance methods (static methods are not polymorphic, as the previous answer showed).
What you can do is to make your classes not directly implement Bar, but another interface (e.g. BarProvider) with a toBar() or getBar() method, which returns a custom object of type Bar, which behaves as you want.
public class A implements BarProvider{
#Override
public int hashCode(){ return 1;}
#Override
public Bar toBar() {
return new Bar() {
#Override
public int hashCode() { return 123; }
};
}
}
A aObject = new A();
interfaceObject.hashCode(); //return 1;
Bar interfaceObject = aObject.toBar();
interfaceObject.hashCode(); // return 123
Several improvements are possible, such as having the Bar object stored as a final field (to avoid multiple initializations), and having a reverse reference that allows you to get back from the Bar to its BarProvider.
Another possibility is to use an external provider, that makes your computations
public class A implements Bar{
#Override
public int hashCode(){ return 1;}
}
public final class BarHasher implements Hasher<Bar> }
#Override
public int hashFor(Bar object) { return 123; }
}
A aObject = new A();
interfaceObject.hashCode(); //return 1;
BarHasher.hashFor(aObject); // return 123
or a static method that calls some other method
public class A implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int hashAsBar() { return 123; }
}
public interface BarHasher implements Hasher<Bar> {
#Override
public int hashFor(Bar object) { return object.hashAsBar(); }
}
A aObject = new A();
interfaceObject.hashCode(); //return 1;
BarHasher.hashFor(aObject); // return 123
In case you don't know it, what you're trying to do is possible (and it's the default behavior) in C++ (you must declare methods as virtual to have the same behavior as Java) and in C# (but you will have a warning, unless you use the modifier new on the overriding method)
There's no way to do this that I know of.
Here's something you can do that you may not have known of (I'm not suggesting this is a good idea):
package com.sandbox;
import java.io.IOException;
public class Sandbox {
public static void main(String[] args) throws IOException {
A.speak();
B.speak();
A a = new A();
a.speak(); //my ide rightly gives a warning here. static function accessed through instance
A b = new B();
b.speak(); //my ide rightly gives a warning here. static function accessed through instance
}
public static class A {
public static void speak() {
System.out.println("A");
}
}
public static class B extends A {
public static void speak() {
System.out.println("B");
}
}
}
This will print:
A
B
A
A
Just to reiterate: This is NOT a good idea. I'm just letting you know for educational purposes.
It's easy to invoke different methods based on the declared type of a variable. That's called overriding, and here's an example of it:
public class Example {
public static void main(String[] argv) throws Exception {
Integer v1 = 12;
Number v2 = v1;
System.out.println(v1.hashCode() + " -> " + new KeyWrapper(v1).hashCode());
System.out.println(v2.hashCode() + " -> " + new KeyWrapper(v2).hashCode());
}
private static class KeyWrapper {
private Object obj;
private int hash;
public KeyWrapper(Integer v) {
this.hash = v.hashCode() * 3;
}
public KeyWrapper(Number v) {
this.hash = v.hashCode() * 5;
}
#Override
public int hashCode() {
return hash;
}
}
}
When you run this, you get the following output:
12 -> 36
12 -> 60
Why this is a bad idea is that you can't implement equals() in in a way that preserves its contract (which is that two equal objects must have equal hashcodes). At compile-time you have information about how the values are referenced, but at runtime you only know what they are.
That said, if you want to use different hashcode calculations for objects that do implement an interface, versus those that don't, you can write a KeyWrapper that uses instanceof.
public class Example {
public static void main(String[] argv) throws Exception {
Integer v1 = 12;
String v2 = "foo";
System.out.println(v1.hashCode() + " -> " + new KeyWrapper(v1).hashCode());
System.out.println(v2.hashCode() + " -> " + new KeyWrapper(v2).hashCode());
}
private static class KeyWrapper {
private Object wrapped;
public KeyWrapper(Object obj) {
this.wrapped = obj;
}
#Override
public boolean equals(Object obj) {
return wrapped.equals(obj);
}
#Override
public int hashCode() {
return (wrapped instanceof Number) ? wrapped.hashCode() * 3 : wrapped.hashCode() * 5;
}
}
}
This, of course, doesn't care about the declared type of the variable, only its actual type.