【发布时间】:2017-09-10 10:53:32
【问题描述】:
我正在查看this 的答案,但我不明白为什么方法是多态的而不是字段的背后的逻辑。
默认情况下,Java 中的所有成员函数都是多态的。这意味着 当你调用 this.toString() Java 使用动态绑定来解决 call,调用子版本。当您访问成员 x 时,您 访问您当前范围的成员(父亲),因为成员 不是多态的。
当您在父类和子类中都有一些字段x,并在您的子类中覆盖toString,当您在基类中调用以下内容时:
System.out.println(this); //calls the subclass's toString implementation
System.out.println(this.x) //prints the base class's x field
在开头链接的问题中列出的答案中的理由是,当基类在其自己的范围内时,基类不“知道”子类,但是对于多态性,它是同一件事:超类不知道子类存在,但仍然调用子类方法。那么,Java 究竟做了什么让两者的行为有所不同——一种在子类中使用动态绑定,另一种保持超类的范围?
编辑:澄清一下,我不知道为什么 this.x 会做与多态性相同的事情,查看对象的实际类型,而不仅仅是引用类型,并从子类中打印 x 字段.
【问题讨论】:
-
“班级成员”是指“字段”吗?如果是这样,那就更清楚了。方法也是“成员”...
-
@JonSkeet,是的,谢谢。我修好了。
-
从根本上说,每次声明一个新字段时,都会添加更多状态。如果你重写一个方法,你不是在添加一个新方法,你是在替换一个现有签名的实现。任何时候您想要对字段使用“多态性”,可能有更好的设计可以使用...
-
@rb612 我认为(但我可能非常错误),这是因为 x 存储在实例级别,而方法存储在类级别。而 superInstance 根本不存在。您可以从子类调用超类,但是在子类 Instance 中存储 super.x 很奇怪。
-
@JonSkeet 谢谢你的回答,很荣幸得到你的解释!现在在回答最初的问题时给出的解释,即父类不“知道”子类,对我来说没有意义。不是说有了
this.x,Java应该马上看到this这个关键字,就意识到它其实是一个子实例,然后调用相应的方法,就像多态一样?或者在this上调用方法与访问字段时是否有一些不同的过程?
标签: java oop inheritance