Java 中接口为什么可以调用 toString 方法,接口中根本就没有 toString 方法?

作者:蓝枫铭
链接:https://www.zhihu.com/question/24113953/answer/27172633
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

感谢 @pansz 提供的官方链接,遗憾的是他的解释并不准确:
原文:
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throwsclause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
也就是说:
如果一个接口定义是最顶级的(没有 super interfaces),那么这个接口会自动声明一个 abstract member method 结构体来代表所有来自 Object 类(一切类的superclass)中的public方法(包括这些方法的签名、返回类型以及抛出的异常)

为什么要这么做?
让接口型的(interface Type)父类引用也可以拥有Object类的一般方法( toString()、equals() 等)
interfaceName A = new className();
A.toString();

为什么不是继承
这源于继承的概念:因为你只能继承 
  • 父类 的定义了结构体(具体实现)的方法①
  • 非abstract 的方法②(abstract的方法需要通过实现的方式来"继承")
但是接口是不可以拥有上述两种方法的(interface's methods must be public abstract, the body must be empty)
所以,是接口重新声明了Object类的通用行为规范,而不是继承了。

看例子:
interface A{}

class B implements A{
    public String testB(){
        return "testB() from class B";
    }
}

public class Demo{
    public static void main(String[] args) {
        A a = new B();
        System.out.println( a.toString() );
        System.out.println( a.equals(null) );
        
        // System.out.println( a.testB() ); // 取消本行注释将无法通过编译(compiler error)
        /* D:\Developer\tmp>javac Demo.java
         * Demo.java:14: 错误: 找不到符号
         *     System.out.println( a.testB() ); 
         *                          ^
         * 符号: 方法 testB()
         * 位置: 类型为A的变量 a */
        // casting a to B type
        System.out.println( ((B)a).testB() );
    }
}

/* -------- output --------
D:\Developer\tmp>java Demo
B@327800e9
false
testB() from class B
---------------------------*/

最后,一定要看这里:
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页