0

Looking at great example Polymorphism vs Overriding vs Overloading , consider this scenario:

abstract class Human {

  public void goPee() {
    println("drop pants");
  }
}

class Male extends Human {

  public void goPee() {
    super.goPee();
    println("stand up");
  }
}

class Female extends Human {
  public void goPee() {
    super.goPee();
    println("sit down");
  }
}

My questions:

  1. Is it possible, on concrete classes level, to enforce using super.goPee() inside goPee() ? if so - how ?

  2. Is it possible, on abstract class level, to know which concrete class had called super.goPee() ? Rationale for that is if I would need to call method let's say liftToiletSeat() somewhere on abstract class level.

Thank you.

Community
  • 1
  • 1
mtx
  • 1,196
  • 2
  • 17
  • 41
  • (talking about your example) – Anubian Noob May 29 '14 at 18:32
  • yes, particularly on my first question. – mtx May 29 '14 at 18:35
  • you could argue that this is the childs class responsibility. If the child class just doesn't want any hassle, sure, call the parents class which should be enough for everyone. I would even go as far as saying your function shouldn't need anything more for it to be complete, but that is besides the point. Lets say another Human, `child` doesn't wear pants, so it has got its own way of peing. (just `println("make_a_mess");` I guess). (This class wouldn't want to call the parent. Or if it for some other reasons want to implement everything itself: why disallow that) – Nanne May 29 '14 at 18:36

1 Answers1

2

You can enforce it by not giving the subclass a choice, by using a simple Template Method Pattern. In the superclass that wants to enforce a call to super, don't give a choice.

Make the method final so it can't be overridden, and then call an abstract protected method that must be overridden. The superclass behavior is enforced.

abstract class Human {

   public final void goPee() {
       System.out.println("drop pants");
       toStandOrNotToStand();
   }

   protected abstract void toStandOrNotToStand();
}

Then the subclass can't override the superclass method, so it can't decide not to call super, but it must override the abstract method to be concrete.

class Male extends Human {
    @Override
    protected void toStandOrNotToStand() {
        println("stand up");
    }
}

And Female can be done similarly.

It is possible to know the concrete class with the getClass() method, but it doesn't make sense to do subclass-specific behavior in a superclass. You should be able to have liftToiletSeat in the Male subclass.

rgettman
  • 176,041
  • 30
  • 275
  • 357