无法调用从接口实现的 child class 中的方法

Cannot call method in child class that implements from interface

根据这个 answer 我试着这样实现它

摘要class(飞行员):

public abstract class Pilot{
    abstract void fly();
}

界面(安全官):

public interface ISafetyOfficer {
        void controlSafety();
}

Child class:

public class C141 extends Pilot implements ISafetyOfficer{
    void fly(){ 
        System.out.println("I'm flying C-141.");
    }

    public void controlSafety(){
        System.out.println("I'm control safety.");
    }

并且在 Main class 的 main() 中无法调用 controlSafety() 方法

public class Main {
    public static void main(String[] args) {
        Pilot pilot = new C141();
        pilot.fly();
        pilot.controlSafety(); // Cannot call controlSafty here.
    }
}

函数 main() 出现问题。谁能告诉我为什么我不能以 OOP 方式调用 controlSafety() 方法。

基本上,因为controlSafety不是Pilotclass的特征之一。因此,当您尝试从 Pilot 声明的对象调用 controlSafety 时,编译器会检查它是否在 Pilot class 中声明,否则不允许您调用它.

所以C141是一个Pilot也是一个ISafetyOfficer

但是 Pilot 不是 ISafetyOfficer

您可以将 C141 转换为 ISafetyOfficer,然后调用它。 Java 不是鸭子类型的语言。

因为您将 C141 class 向上转换为 Pilot 摘要 class。但是 Pilot class 没有 controlSafety() 方法。

Pilot class 没有方法 controlSafety() 这就是编译器找不到该方法的原因。

Pilot pilot = new C141() 它是多态性,但只有 Pilot class 中存在的方法将被调用,而不是从方法接口 ISafetyOfficer 被调用。

语句 Pilot pilot = new C141(); 的左侧 hand/reference 变量决定了可以在分配给它的对象上调用哪些方法。在这种情况下,它的类型为 Pilot,并且由于 Pilot class 没有方法 controlSafety(),因此无法使用类型 Pilot 的引用来调用它。在这种情况下,您可以通过类型转换来解决问题:-

  Pilot pilot = new C141();
  pilot.fly();
  C141 c=(C141)pilot;
  c.controlSafety();
  //or
  ISafetyOfficer isafe=(ISafetyOfficer)pilot;
  isafe.controlSafety();

同样从 OOP pov 来看,飞行员是为了飞行而不是控制安全,这就是 Isafety officer 的目的,因此你不能告诉飞行员做 controlSafety。理想的方式应该是:-

  Pilot pilot = new C141();
  pilot.fly();
  ISafetyOfficer isafe=new C141();
  isafe.controlSafety();