如何使用父对象引用调用子类的非重写方法



这是我的代码想要访问AdapterVer1的子类方法getAdaptObj1()(没有类型转换)使用AdapterVersion(父类)的对象引用

abstract class AdapterVersion {
public abstract void getMObject();
public abstract void getCObject();
}
public class AdapterVer1 extends AdapterVersion {
@Override
public void getMObject() {
    System.out.println("AdapterVer1 Mont");
}
@Override
public void getCObject() {
    System.out.println("AdapterVer1 Conf");
}
public void getAdaptObj1() {
}
}
public class AdapterFactory {
public static void main(String []a){
    AdapterFactory adapterFactory= new AdapterFactory();
    AdapterVersion adpater = adapterFactory.getMyObject("ver1");
    adpater.getAdaptObj1();  // Unable to do that
            ((AdapterVer1)adpater).getAdaptObj1(); // Working but DONT WANT THIS
}
public AdapterVersion getMyObject(String version){
    if(version.equals("ver1")){
        return new AdapterVer1();
    }else{
        return new AdapterVer2(); // another declared class
    }
}
}

你不能那样做。因为在编译时,编译器会检查所调用的方法在所使用的引用的类中是否可访问或可见。

因此,在这种情况下,由于引用是Parent类,编译器将首先在Parent类中查找方法声明,以便成功编译代码。

记住:-

编译器关心的是引用类型,而在运行时,要考虑实际的对象类型,以决定实际调用哪个方法。

您唯一的选择是类型转换,在这种情况下,编译器现在查看您对引用进行类型转换的类。另一种选择是,您可以在Parent类中声明一个具有该名称的抽象方法,但从您的问题来看,似乎您明确没有这样做。

您需要将方法声明移动到抽象类中。

Rohit已经解释得很好了。再补充一点,您应该首先检查子类类型,然后再进行类型转换,例如:

if(adapter instanceof Adapterver1) {
    ((AdapterVer1)adpater).getAdaptObj1();
}

这样,当你的代码试图处理一个没有声明这种方法的新子类时,你的代码会更安全。

但是你必须问的问题是,如果你已经知道要调用的子类方法,为什么要从超类引用访问它?