简体   繁体   中英

Calling method that exists in child classes but not in parent class

public class Parent {
    ....
}

public class Child1 extends Parent {
    ....
    public void foo() {
        ....
    }
}

public class Child2 extends Parent {
    ....
    public void foo() {
        ....
    }
}

Here method foo() only exists in the Child classes and CAN NOT be added to the Parent class (not even abstract method). In this situation when I want to call the foo() method on obj which is Parent class's reference then I need to use intanceof with multiple if..else which I want to avoid.

Parent obj = ...// Object of one of the child classes
obj.foo();

EDIT: I Need to use type of obj as Parent only. Else I will not be able to call methods on obj which exists in Parent class.


My Solution: The approach that I am thinking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:

if(obj instanceof FooInterface){
    ((FooInterface)obj).foo();
}

Is there a better approach ? Or any improvement to this one?

The polymorphism is applied on object reference, not a type. When you call

FooInterface obj = ...// Object of one of the child classes
obj.foo(); 

the child class method foo() is called.

You can't do it with parent object reference until an unless method is declared in parent class/interface itself.

You have to downcast it to child class because parent class/interface doesn't have any knowledge about the child class other than the contract defined between them.

Here contract means abstract methods .


you can try in this way where there is no need to put a check it.

FooInterface sc =new Child1();
sc.foo();

...

interface FooInterface{
    void foo();
}

public class Parent {

}

public class Child1 extends Parent implements FooInterface{

    public void foo() {

    }
}

public class Child2 extends Parent implements FooInterface{

    public void foo() {

    }
}

The approach that I am finally taking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:

Parent obj = ...// Object of one of the child classes
.....
if(obj instanceof FooInterface){
    ((FooInterface)obj).foo();
}

If you want to typecast only then there is no need of adding interface. You can typecast it to your desired class and call the method. Example

public class HelloWorld {
    public static void main(String args[]) throws FileNotFoundException {
        SuperClass sc =new Child1();
        if(sc instanceof Child1)//Do same for Child2
        ((Child1)sc).foo();
    }
}

class SuperClass {

}

class Child1 extends SuperClass{
    public void foo(){
        System.out.println("From child1");
    }
}

class Child2 extends SuperClass{
    public void foo(){
        System.out.println("From child2");
    }
}

Output : From child1

You could implement an AbstractChild inheriting from Parent and then extend this class instead of Parent :

public class Parent {
    ....
}

public abstract class AbstractChild extends Parent{

    public abstract void foo();

}



public class Child1 extends AbstractChild {
    ....
    public void foo() {
        ....
    }
}

public class Child2 extends AbstractChild {
    ....
    public void foo() {
        ....
    }
}

So you need to only check if your instance is instanceof AbstractChild .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM