2
public class BaseClass {
    private String className;

    public BaseClass() {
        className = "[BaseClass]";
    }

    public void executeAB() {
        System.out.println(className + " executingAB()");
        executeA();
        executeB();
    }

    public void executeA() {
        System.out.println(this.className + " executingA()");
    }

    public void executeB() {
        System.out.println(this.className + " executingB()");
    }
}


public class SubClass extends BaseClass {

    private String className;

    public SubClass() {
        this.className = "[SubClass]";
    }

    public void executeA() {
        System.out.println(className + " executingA()");
    }

    public void executeC() {
        System.out.println(className + " executingC()");
    }

    public static void main(String[] args) {

        BaseClass t = new SubClass();
        t.executeAB();
        // t.executeC();
    }
}

In above case , Calling t.executeAB() results in output:

[BaseClass] executingAB()

[SubClass] executingA()

[BaseClass] executingB()

My Question is:

How does BaseClass know about excuteA() method from SubClass, while at the same time t.executeC() call is not possible because BaseClass is not aware of executeC().

Community
  • 1
  • 1
Karmjit
  • 85
  • 6
  • 12
    The answer is BaseClass *doesn't* know about how or if a method is overridden, and the magic of OOP is that it *doesn't have to know*. This is all handled behind the scenes by a method [dynamic dispatch](http://en.wikipedia.org/wiki/Method_dispatch) table. – Hovercraft Full Of Eels Jun 17 '13 at 00:57
  • This is one of the basic reason of having inheritance in OOPs word. – Sandeep Jindal Jun 17 '13 at 01:42

2 Answers2

2

You have a misunderstanding of what you should be doing in inheritance. extends is a reserved word that was wisely chosen. The point of B extending A is to say that B is a subset of A with additional attributes. You're not supposed to redefine x in B; A should be handling x. You should have not className declared in both classes.

As for your example:

 BaseClass t = new SubClass(); 

Calls the constructor for SubClass, which sets className of SubClass to [SubClass]. The super contructor is also called, and className in BaseClass is set to [BaseClass].

 t.executeAB();

Prints the className for BaseClass which is [BaseClass] and then calls:

 executeA(); 
 executeB();

executeA() is a called from SubClass, since t is a SubClass and it's defined, so we get [SubClass] and finally, executeB() is called from BaseClass so again, we get [BaseClass]. As for why you can't call:

t.executeC()

Despite using the constructor for SubClass, t is a BaseClass. According to the principles of OOP, it makes sense that you can't call t.executeC(), since it is not defined for BaseClass.

Steve P.
  • 14,489
  • 8
  • 42
  • 72
  • thanks steve. you mentioned "You're not supposed to redefine x in B", then what is use of overriding? do you mean i should have overriden executeAB() instead? – Karmjit Jun 17 '13 at 01:39
  • [Overriding](http://docs.oracle.com/javase/tutorial/java/IandI/override.html) is for redefining a method in a subclass. For example, overriding `toString()` makes sense because we want to be able to have a `String` representation of our objects (which may need to be different than our parent's `toString()`). I'm not sure what your intentions were, but you're never going to be able to call `executeC()` on a `BaseClass` unless it's defined in `BaseClass` or one of its superclasses...Also, since you're new, you should check out the [tour](http://stackoverflow.com/about). – Steve P. Jun 17 '13 at 01:45
0

You're defining your variable as BaseClass t = new SubClass(); which means you allow space for a different subclass to instantiate. However, in order for this to be possible without breaking existing code, you can only use methods that are defined in the baseclass.

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170