0

Clarification: My question is not about overriding vs overloading functions. It's about overriding methods in superclasses that use composition.

Lets say I have two classes, A and B. They're really useful together, so I make another class composed of the two, called AB. The problem with this is that subclasses of AB have difficulty overriding A/B's methods. I'm looking for suggestions on how to mitigate the effect described below.

Example:

A: Has a function that calls another one of its own functions. In this case, loopA(int num) loops and performs a() num times.

public class A {
    public void loopA(int num){       
        for(int i = 0; i < num; i++){   
            a();
        }
    }

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

B: Just random functionality.

public class B {
    public void b(){
        System.out.println("B");
    }
}

AB: A combination of the two.

public class AB {
    A a = new A();
    B b = new B();

    public void loopA(int num){
        a.loopA(num);
    }

    public void a(){
        a.a();
    }

    public void b(){
        b.b();
    }
}

ValidatedAB: AB that validates before performing a()

public class ValidatedAB extends AB{
    @Override
    public void a(){
        System.out.println("Validate A!");
        super.a();
    }
}

Problem

My problem is that calling ValidatedAB.loopA(int num) will NOT call the overridden a() in ValidatedAB, but the original A.a().

    ValidatedAB vab = new ValidatedAB();
    vab.loopA(2);

    //Desired Output:
    Validate A!
    A
    Validate A!
    A

    //Actual Output:
    A
    A

Possible Solutions

1. Copy/Paste or Refactor A and B into AB

A simple solution that gets rid of composition but results in a large AB class, and is also code duplication if we keep A, B, and AB.

2. Subclass A and B separately, and inject both into ValidatedAB.

public class ValidatedA extends A {
    @Override
    public void a(){
        System.out.println("Validate A!");
        super.a();
    }
}

public class ValidatedAB extends AB{
    public ValidatedAB(A a, B b){
        this.a = a;
        this.b = b;
    }
}

ValidatedAB vab = new ValidatedAB(new ValidatedA(), new B());
vab.loopA(2);

This will cause a lot of classes to be made (my team members hate that). It also exposes the fact that AB is a composition of A and B (not a terrible thing in this scenario considering AB has the same interfaces, but otherwise would probably get some dirty looks). Finally, it still has the same overriding problem if ValidatedAB is subclassed.

Conclusion

I'm hoping to find a clean, non-bulky, encapsulated way to achieve the effect I'm trying to get, but I know there are always trade offs. As a junior developer, any suggestions would be greatly appreciated. Thanks.

GuitarStrum
  • 713
  • 8
  • 24
  • 1
    I don't see why this was marked as a duplicate for the difference between overloading and overriding. That's not my problem here. My question is about overriding methods in superclasses that use composition. – GuitarStrum Feb 15 '18 at 06:35
  • I've renamed a(int num) to loopA(int num) to be clearer. – GuitarStrum Feb 15 '18 at 06:41

1 Answers1

0

It does override the method a() but not the method a(int) - just add an additional override for the method with its parameters or add the parameter to your override.

Java sees both method as different ones.

Felix Gaebler
  • 702
  • 4
  • 23
  • I'm not looking at a() and a(int); I'm looking at a(int) calling a() in a combination of composition and subclassing the composed superclass. – GuitarStrum Feb 15 '18 at 06:31