简体   繁体   English

从java子类调用不在父类中的方法

[英]Calling method from java child class not in parent class

Consider the following base/derived classes: 考虑以下基类/派生类:

public class Car {
    private int cylinders;

    public Car(int cyl) {
        cylinders = cyl;
    }

    public int getCylinders() {
        return cylinders;
    }
}

public class SportsCar extends Car  {
    private int topSpeed;

    public SportsCar(int cyl, int top) {
        super(cyl);
        topSpeed = top;
    }

    public int getTopSpeed() {
        return topSpeed;
    }
}

Now, consider the following two objects: 现在,考虑以下两个对象:

    SportsCar lambo = new SportsCar(8,255);
    Car m5 = new SportsCar(10,240);

The following method call compiles fine: 以下方法调用编译正常:

lambo.getTopSpeed();

However this method call breaks with the error "cannot find symbol - method getTopSpeed()" 但是这个方法调用中断错误“找不到符号 - 方法getTopSpeed()”

m5.getTopSpeed();   

Now I understand that the getTopSpeed method must exist in the base class in order for it to compile since m5 is a Car type, so if I include getTopSpeed in Car then m5.getTopSpeed(); 现在我明白getTopSpeed方法必须存在于基类中才能编译,因为m5Car类型,所以如果我在Car包含getTopSpeed那么m5.getTopSpeed(); compiles nicely. 编译得很好。

My questions are: 我的问题是:

  1. Why does the error "cannot find symbol - method getTopSpeed()" happen at compile time and not run time? 为什么错误“找不到符号 - 方法getTopSpeed()”发生在编译时而不是运行时?
  2. Why doesn't "late binding" prevent this error? 为什么“后期绑定”不会阻止此错误?
  3. Assuming getTopSpeed is implemented in Car (so it compiles) when the program is run, does the compiler first check to see if getTopSpeed exists in Car and then checks to see if it is over-ridden in SportsCar or does it just "know" that it is over-ridden already from the compiler and directly uses the over-ridden method? 假设getTopSpeed在程序运行时在Car中实现(所以它编译),编译器是否首先检查Car是否存在getTopSpeed ,然后检查它是否在SportsCar被覆盖,或者只是“知道”它已经从编译器中过度使用并直接使用过度使用的方法?
  1. Java is statically typed language, so a variable type should be known at compile time. Java是静态类型语言,因此在编译时应该知道变量类型。 If type that is known to the compiler doesn't expose such a method - it is compilation failure. 如果编译器已知的类型没有公开这样的方法 - 则编译失败。 Exactly for the reason to not let it to runtime. 正是因为不让它运行的原因。

  2. Why should it? 为什么要这样? It just finds the method body late, not signature. 它只是发现方法体迟到了,而不是签名。 Still, static typing means that signature must be satisfied at compile time. 但是,静态类型意味着必须在编译时满足签名。

  3. At runtime JVM tries to find the most specific implementation. 在运行时,JVM尝试查找最具体的实现。 In SportsCar, in your case. 在SportsCar中,在您的情况下。 If it is inherited from parent but absent in child - parent's code is used. 如果它是从父级继承而在子级中不存在 - 则使用父级代码。

If you need to call method from specific child which is absent in variable type - you can cast it at runtime at your own risk of getting ClassCastException. 如果需要从变量类型中缺少的特定子项调用方法 - 您可以在运行时将其强制转换为ClassCastException。

This is because when the compiler sees this: 这是因为当编译器看到这个时:

SportsCar lambo = new SportsCar(8,255);
Car m5 = new SportsCar(10,240);

It knows lambo is a SportsCar, but only knows m5 is a Car. 它知道lambo是一款SportsCar,但只知道m5是一辆Car。 If you want get the top speed for m5, you'll have to cast it to a SportsCar first: 如果你想获得m5的最高速度,你必须先将它投射到SportsCar:

((SportsCar)m5).getTopSpeed();

Most of the time I've seen casting, however, the variable is cast to another variable first: 然而,大多数时候我看过铸造,变量首先被转换为另一个变量:

SportsCar sportsM5 = (SportsCar)m5;
sportsM5.getTopSpeed();

This aspect of polymorphism in Java confused me once when I was passing an object to a method. 当我将对象传递给方法时,Java中的多态性的这一方面使我感到困惑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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