a3dsfcv
a3dsfcv

Reputation: 1274

Overriding a base class method in a derived class

I have a base class A, having a method "say" that calls from constructor of A. All the heritable classes uses the method "say" like it is. But one of the classes need to redefine this method. How is it possible?

For sure, I can denote base method "say" as abstract, but in that way, i have to copy the same method "say" in all the heritable classes.

If i just redefine method without denoting base one as abstract, it is not gonna be called.

public abstract class A(){
     public A(){
        say();  //  <- wanna call this method from heritable class, if its redefined. 
     }
     protected void say(){};
}

public class B extends A(){
     public B(){
        super();
     }
     private void say(){};
}

refactoring 1

public abstract class A(){
     public A(){
       //  constructor methods             
     }
     protected void say(){};
     protected void executeSay(){
       say();
     }
}

public class B extends A(){
     public B(){
        super();
        executeSay();
     }
     @Override
     protected void say(){};
}

Upvotes: 0

Views: 6513

Answers (4)

Yogesh Patil
Yogesh Patil

Reputation: 888

You cannot instantiate a abstract class. That saying you have to link the abstract class reference to the concrete inherited class. eg. A a = new B(); If that's the case, and B have redefined the say() method, then the say method in B will be called.

public class TestPad {
    public static void main(String[] args) {
        A a = new B();
    }
}
abstract class A {
    public A() {
    say();
    }
    public void say(){
    System.out.println("A");
    };
}

class B extends A {
    public B() {
    super();
    }
    public void say() {
    System.out.println("B");
    }
}

The output will be B

Upvotes: 4

Marko Topolnik
Marko Topolnik

Reputation: 200148

First of all one must be made clear: calling an overridable method from a constructor is a well-known antipattern. It will almost certainly break your code because the subclass method will be invoked before the subclass constructor is done and so will observe an uninitialized object. Thus I should better refrain from giving you detailed advice on Java technicalities involved in achieving this antipattern.

The only safe way to acomplish your requirement is to let the construction finish and only afterwards call an initialize-kind of method. If you want to ensure initialize is always invoked, make the constructors non-public and provide a factory method instead.

Unfortunately, Java requires quite a bit of work on your part to make this work properly.

Upvotes: 11

Michal Borek
Michal Borek

Reputation: 4624

Because of polymorphic method invocation, in your case the B.say() will be invoked if you override it.

But as @sanbhat commented, you need to change visibility of say() to protected.

Upvotes: 0

Marco Forberg
Marco Forberg

Reputation: 2644

public class B extends A {
    public B() {
        super();
    }

    @Override
    protected void say() {
        // your diffent say code
    };
}

I'm not sure if you are allowed to reduce visibility to private.

Upvotes: 3

Related Questions