Java 接口是否被视为对象?
为什么下面的代码可以工作Java 接口是否被视为对象?,java,Java,为什么下面的代码可以工作 interface I { } class A implements I{ public String toString(){ return "in a"; } } class B extends A{ public String toString(){ return "in b"; } } B b = new B(); A a = b; I i = a; System.out.println(i); System.out.println((B)a
interface I { }
class A implements I{
public String toString(){ return "in a"; }
}
class B extends A{
public String toString(){ return "in b"; }
}
B b = new B();
A a = b;
I i = a;
System.out.println(i);
System.out.println((B)a);
System.out.println(b);
如您所见,i
是println
方法的有效参数。为什么?通过查看此方法接受的参数类型,似乎只有对象是相关的
我在寻找答案,发现了一些相关的东西:
引用类型都继承自java.lang.Object。类、枚举、数组和接口都是引用类型
但也发现了这个问题:“接口是否继承自Java中的对象类?”答案是:不,它们不是。在这方面,也没有公共的“根”接口隐式地由所有接口继承(与类的情况一样)。(*)
这是什么意思?有人能解释一下为什么接口被接受为println
函数的参数吗
我想这里的要点是,如果没有对象本身,就无法通过接口传递对象
但问题仍然存在。为什么编译器接受接口作为此方法的参数?是这样的。您不能实例化接口,因此任何对接口的引用都必须指向实现该接口的某个类的对象。并且该对象的超类在某个点上必须是object。对此进行了解释: 给定非泛型类型声明C,类型C的直接超类型如下所示: C的直接超类(§8.1.4) C的直接上界面(§8.1.5) 类型对象,如果C是没有直接超级接口的接口类型(§9.1.3)
您可能会问,为什么对象是任何接口的超类型。原因是对象不能不作为具体类的实例,这个具体类也不能不扩展对象。因此,编译器知道对接口类型的引用就是对对象的引用。您的误解源于混淆。继承和子类型是分开的 解释继承的含义: 接口
I
从其直接上级接口继承所有抽象和默认方法m
[…]
当您有类似于类字符串扩展对象{}
的内容时,字符串
是对象
的子类型,因此继承超类对象
的成员
另一方面,接口是
对象的子类型,但不从中继承成员。这就是解释,接口不会继承的原因。编译器与其说接受接口,不如说接受参数,而是对碰巧实现接口的对象的引用。考虑下面的代码片段,类似于您的代码,以及输出。您将看到,在这两种情况下,输出都是Box对象。在这两种情况下传递给println()的参数(或“thing”)是同一个Box对象。只是在一种情况下,它被称为Box的具体实例化,而在另一种情况下,它被称为实现a接口的对象
interface A {}
public class Box implements A
{
public Box()
{
}
public static void main(String[] args)
{
Box b =new Box();
A a = b; //define a reference to an object that implements interface A
System.out.println(a);
System.out.println(b);
}
}
输出为:
Box@19e0bfd
Box@19e0bfd接口不继承对象
,但实现任何接口的任何实例都继承对象
,toString()
方法也是如此。我想,当调用System.out.println(..)时,如果将对象传递给它,编译器就会调用它的toString(),因此,理想情况下,我们传递的是一个字符串。@SashaSalauyou:不确定toString
的相关性是什么…@SashaSalauyou相关性不大。它只是为了打印消息和查看方法调用而添加的System.out.println
调用对象上的toString
方法。编译器知道i
实现了接口,因此i
扩展了object
。给定一个名为Countable
的接口
,我能够将已初始化为null
的Countable
类型的引用传递给println
语句。既然null
不是一个对象,那么它是如何工作的呢?@ChetanKinger我们这里讨论的是类型,而不是对象。类型对象
总是类型可数
@biziclop的直接(或间接)超类型。这个答案说每个对象都是某个具体类的实例
。我想知道这与OP中的问题以及我在前面评论中的问题有什么关系。也就是说,你的意思是说java
中的所有引用都是Object
?@ChetanKinger它不是直接相关的,因为JLS规则说每个接口类型都直接或间接地将Object作为其超类型。但您可能会问,为什么对象是任何接口的超类型,原因是对象不能不作为具体类的实例,这个具体类也不能不扩展对象。@JBNizet您的编辑有意义,因为您添加了一些上下文:)