如果类实现了接口并且具有toString()
方法
我们将子引用存储到父变量中,或者只是完成动态绑定
那么为什么编译器没有检查接口中的toString()
方法,因为它是一个规则
函数唯一性的动态绑定将在父级中检查
例如
interface my {
void show();
}
class child implements my {
public void show() {
System.out.println("working");
}
public String toString() {
return "hello";
}
public static void main(String... s) {
my m = new child();
m.show();
String s = m.toString();
System.out.println(s);
}
}
我们知道,每当动态绑定完成时,除非已覆盖上述方法,否则无法执行子个人方法
那么为什么上面的函数toString()
得到了编译并给出了输出?
答案 0 :(得分:3)
听起来你在问这个问题:
在我的示例代码中,局部变量m
的类型为my
。界面my
只声明了一个方法show()
,那为什么我可以致电m.toString()
?
在Sun(现在的Oracle)Java tutorial on inheritance中解释了这一点:
类可以从派生自类的类派生的类派生,依此类推,而最终派生自最顶层的类。这样的类据说是来自继承链中的所有类都延伸回Object。
The Object
class声明了一个默认的toString()
方法(以及其他一些基本方法),因此您可以在任何对象上调用toString()
。
<强>更新
由于Java 中的所有类实例必须继承自Object,因此将接口用作类型的实际语义更像是:
public static void main(String... s) {
// This won't actually compile
(? extends Object implements my) m = new child();
m.show();
String s = m.toString();
System.out.println(s);
}
换句话说,当您声明m
类型为my
时,您实际上是说m
是实现接口Object
的某些my
。由于Object
声明了toString()
方法,即使m.toString()
界面中不存在toString()
,您也可以致电my
。
Java是专门设计的,在类层次结构的顶部有Object
,所以你无法让编译器抱怨在任何对象的任何实例上调用toString()
。 hashCode()
,equals()
等也是如此。
答案 1 :(得分:1)
我认为你的问题将通过已经给出的两个答案来解决。我只是想指出一些关于你的陈述的事情: -
if a class implements an interface and have a toString() method
您定义的任何类都有toString()
方法..虽然看起来不太明显,但是当您打印类的实例时,它是toString()
类的Object
方法调用它。(Object
类是您定义的所有其他类的超类。)因此,Object
类中定义的任何方法都可以从任何其他class object
访问。
您可以覆盖此方法以根据需要打印您的实例。但是,如果没有覆盖,您将获得对象的hashcode
..(例如: - classname@12343
。现在由于这个toString()
方法适用于所有类,编译器不需要在任何interface
中检查它。它知道toString()
方法是Object
的一部分} class是所有类的super class
..
we store the child reference into parent variable
虽然你的理解是正确的,但让我重新构思这句话,使其更有意义: - We Store the reference to child class object in the parent class reference variable
function uniqueness will be check in parent
我真的无法理解,这句话是什么意思..但据我所知,你是这么说的 - “当child class
上调用parent class reference
的方法时,然后编译器将首先检查该方法是否在parent class
中定义,然后只能调用该方法..
*编辑* : -
根据Java Language Specification,第9.2节: -
如果接口没有直接的超级接口,那么接口 隐式声明带有签名的公共抽象成员方法m s,返回类型r,以及对应于每个公共的throws子句t 具有签名s的实例方法m,返回类型r和throws子句t 在Object中声明,除非具有相同签名的方法相同 返回类型,并且显式声明了兼容的throws子句 界面。
如果接口明确声明了这样的,那么这是一个编译时错误 方法m在m被声明为Object的最终的情况下。
如果接口声明了,那么这是一个编译时错误 具有覆盖等效(§8.4.2)的签名的方法 Object的公共方法,但具有不同的返回类型或 不兼容的投掷条款。
答案 2 :(得分:0)
所有对象都延伸Object
。 public String toString()
中定义了Object
,因此所有对象都有toString()
方法。
答案 3 :(得分:0)
如果你问我认为你在问什么,那是因为Java中的每个非原语(原语是int
,long
等;但不是String
)类型Object
。 Object
有方法toString()
,hashCode()
和equals()
,这意味着任何非基元也都有这些方法。
但是,这些方法通常过于通用,无法用于特定的类,这就是我们在需要时重载它们的原因。