Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 确定实际调用的覆盖方法_Java - Fatal编程技术网

Java 确定实际调用的覆盖方法

Java 确定实际调用的覆盖方法,java,Java,例如,当子类对象被强制转换为其超类时 Superclass obj = new Subclass(); 并且定义了类 public class Superclass{ public void thisMethod(){ System.out.println("Superclass version was executed"); } 及 当调用obj.thisMethod()时,我得到的子类版本被调用为输出,这显然意味着调用了子类中定义的该方法的版本(原始超类对象无法“

例如,当子类对象被强制转换为其超类时

Superclass obj = new Subclass();
并且定义了类

public class Superclass{
    public void thisMethod(){
        System.out.println("Superclass version was executed");
}

当调用
obj.thisMethod()
时,我得到的
子类版本被调用为输出,这显然意味着调用了子类中定义的该方法的版本(原始超类对象无法“执行”的版本),尽管声明的类型是超类,是吗?
因此,即使子类方法是在obj上执行的,
调用
obj.newMethod()
时,我得到一个编译错误

基本上,为什么在通过超类对象调用的子类中定义了
thisMethod()
的版本?我知道,
obj
的实际类型仍然是子类,因此自然应该调用新版本,但是,我是否应该能够调用
obj.newMethod()

谢谢你的解释(:

编辑:表示在标题中被覆盖*

基本上,为什么在通过超类对象obj调用的子类中定义thisMethod()的版本

因为这基本上是继承点-它允许实现重写,而调用代码不需要知道正在使用哪个实现。以
InputStream
为例-您可以使用
InputStream
进行编码,然后无论是否传递了
FileInputStream
,一个
ByteArrayInputStream
等。在抽象类或接口的情况下,您可以调用编译时类型中没有任何实现的方法,但可以保证在执行时使用的具体对象类型中会有一个实现

我知道obj的实际类型仍然是子类,因此自然地,应该调用新版本,但是,我是否应该能够调用
obj.newMethod()

不,因为
obj
的编译时类型是
Superclass
。区分变量的编译时类型(决定哪些方法等可用)和变量值引用的对象的执行时类型(决定哪些方法实现可用)非常重要实际上是这样的


这只是一个非常简短的描述-您应该阅读Java好书中关于继承的一章以了解更多详细信息。

超类obj=new Subclass()在这个定义中,您只能在超类中使用公开的方法。在您的声明中,当您将调用任何方法时,实际上指向子类对象,它将调用子类实现。理论上,
obj
是一个指向
子类
对象的
超类
引用

因为编译器
obj
只是一个
Superclass
,所以所有
Superclass
的方法都可以调用,例如
thisMethod
,编译器不知道对象的类型,只知道引用的类型,因此编译器将拒绝
newMethod
,因为它无法证明此方法存在。

但是在运行时,对象的类型用于分派方法,而不是引用的类型,因此
thisMethod
将解析为
子类的版本

现在,如果我们知道运行时对象的类型是
Subclass
,我们想告诉编译器这一点,我们进行一次转换:

Subclass subobj = (Subclass) obj;
在编译器知道
subobj
属于
Subclass
类型并将接受调用
newMethod
之后,cast只是编译器的一个信息,不会更改对象
obj
中的任何内容,如果
obj
不是
子类,则前面的语句将抛出
ClassCastExcep在运行时执行操作

Subclass subobj = (Subclass) obj;