-1

My code is similar to this:

class Base{
    public void handleObject(A a){
        //more code...
        System.out.println("A");
    }
}

class Sub extends Base{
    public void handleObject(B b){
        //more code specific to this instance and class B
        System.out.println("B");
    }
    public void handleObject(C c){
        //more code specific to this instance and class C
        System.out.println("C");
    }
}

Where B and C inherit from A.

I then want to call handleObject of Base from this code:

//...
Sub s = new Sub();
A[] obj = {new B(), new B(),new C(), new A()};
for(A o:obj){
    s.handleObject(o);
}
//...

And I expect Sub.handleObject(B b) to be called for each object of type B, Sub.handleObject(C c) for type C, and Base.handleObject(A a) to be called for objects of type A.

The real result is it prints "A" three times.

Is it possible to make it work using java's overloading capabilities or must I type check every object myself? If not, what is the best practice to achieve the desired behavior?

This question is very similar to mine but the answers only show why his attempts did not work and did not offer a sufficient solution for me.

I have also tried making it work using Visitor Pattern, but in their example it seems like it is required for the Base class (or at least the interface) to know about Sub, which is something I prefer not to have my project.

Community
  • 1
  • 1
Arthur.V
  • 676
  • 1
  • 8
  • 22
  • 3
    Overloading won't work for this at all, no. Overloading only works on what is known about the types _at compile time._ – Louis Wasserman Apr 27 '17 at 17:48
  • 2
    See [Effective Java: use overloading judiciously](https://github.com/mgp/book-notes/blob/master/effective-java-2nd-edition.markdown#item-41-use-overloading-judiciously). Overriding is runtime, overloading is compile time – Andreas Apr 27 '17 at 17:54
  • Overall it looks like you're misusing inheritance. Inheritance means that the extending item _is-a_ case of the parent type. Trying to have parent types embody specific knowledge of subtypes introduces​ a circular dependency: subtype obviously has to depend on supertype which depends on subtype. Do not do that. Go back and think about what your object model really is. – Lew Bloch Apr 27 '17 at 18:45
  • @LewBloch I dont think I have a dependency of a superclass on a subclass here, could you point me to the problem you're seeing? A can work without B and C(which are more specific cases of A) and Base can work without sub. – Arthur.V Apr 27 '17 at 18:50
  • 1
    You're asking `A` to have different behaviors for method arguments based on compile-time knowledge of an argument type which is a subtype of `A`. – Lew Bloch Apr 27 '17 at 18:54

1 Answers1

1

I suggest you use polymorphism to your advantage. Instead of trying to figure out how to behave for different classes of objects, let each class provide its own behavior:

class A {
  public void handleMyself() {
    System.out.println("A");
  }
}

class B extends A {
  @Override
  public void handleMyself() {
    System.out.println("B");
  }
}

class C extends A {
  @Override
  public void handleMyself() {
    System.out.println("C");
  }
}

class Base {
  public void handleObject(A a) {
    a.handleMyself();
  }
}

class Sub extends Base {
  public static void main(String... args) {
    Sub s = new Sub();
    A[] obj = {new B(), new B(), new C(), new A()};
    for (A o : obj) {
      s.handleObject(o);
    }
  }
}
Andreas
  • 4,937
  • 2
  • 25
  • 35
  • Unfortunately this doesn't make sense in my case. Different instances of Sub should handle the same instances of A/B/C in different ways, so A/B/C dont have a common action. Ill try to clarify that in the question – Arthur.V Apr 27 '17 at 18:11
  • Let me try to flesh out my solution with a more real world use case – Andreas Apr 27 '17 at 18:19