简体   繁体   English

接口是否像对象一样处理?

[英]Are interfaces treated like Objects?

Why is the following code working? 为什么以下代码有效?

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);

As you can see i is a valid parameter to println method. 如您所见, iprintln方法的有效参数。 Why? 为什么? By looking at the parameter types accepted by this method, only object seems to be relevant. 通过查看此方法接受的参数类型,只有对象似乎是相关的。

在此输入图像描述

I was searching for an answer and found a few relevant things here : " Reference types all inherit from java.lang.Object . Classes, enums, arrays, and interfaces are all reference types ." 我正在寻找答案并在此处找到一些相关的东西:“ 引用类型都继承自java.lang.Object 。类,枚举,数组和接口都是引用类型 。”

But also found this: "Do interfaces inherit from Object class in Java?" 但也发现了这一点:“接口是否继承了Java中的Object类?” and the answer: No, they don't. 答案:不,他们没有。 And there is no common "root" interface implicitly inherited by all interfaces either (as in the case with classes) for that matter.(*) 并且没有共同的“根”接口被所有接口隐式地继承(就像在类的情况下那样)。(*)

What does this mean? 这是什么意思? Can someone explain me why is the interface accepted as an argument for the println function? 有人可以解释一下为什么接口被接受为println函数的参数?

I suppose that the point here is that you cannot pass an object through an interface without having the object itself. 我想这里的要点是,如果没有对象本身,就无法通过接口传递对象。

But the question still remains. 但问题仍然存在。 Why is the compiler accepting an interface as a parameter for this method? 为什么编译器接受接口作为此方法的参数?

The JLS explains it: JLS解释说:

Given a non-generic type declaration C, the direct supertypes of the type C are all of the following: 给定非泛型类型声明C,类型C的直接超类型是以下所有:

The direct superclass of C (§8.1.4). C的直接超类(§8.1.4)。

The direct superinterfaces of C (§8.1.5). C的直接超接口(§8.1.5)。

The type Object, if C is an interface type with no direct superinterfaces (§9.1.3). 类型为Object,如果C是没有直接超接口的接口类型(第9.1.3节)。

You might ask why Object is the supertype of any interface. 您可能会问为什么 Object是任何接口的超类型。 The reason is that there is no way for an object not to be an instance of a concrete class, and there is no way for this concrete class not to extend Object. 原因是对象不可能不是具体类的实例,并且这个具体类没有办法不扩展Object。 Hence, the compiler knows that a reference to an interface type is a reference to an Object. 因此,编译器知道对接口类型的引用是对Object的引用。

It is like this. 就是这样。 You can not instantiate an interface, so any reference with an interface must point to an object of some class that implements said interface. 您无法实例化接口,因此任何带接口的引用都必须指向实现所述接口的某个类的对象。 And that object's superclass must be Object at some point. 而且该对象的超类在某些时候必须是Object。

Your misunderstanding stems from a conflation. 你的误解源于一种混淆。 Inheritance and subtyping are separate things. 继承和子类型是不同的东西。

The JLS explains the meaning of inheritance: JLS解释了继承的含义:

An interface I inherits from its direct superinterfaces all abstract and default methods m [...] 一个接口I从它的直接超接口继承所有抽象和默认方法m [...]

When you have something like class String extends Object {} , String is a subtype of Object and thereby inherits members of the superclass Object . 当你有class String extends Object {}东西时, StringObject子类型 ,从而继承了超类Object 成员

Interfaces, on the other hand, are subtypes of Object but do not inherit members from it. 另一方面,接口是Object 子类型 ,但从它继承成员 This is what aioobe's answer is explaining, that interfaces do not inherit. 这就是aioobe的答案所解释的,接口不会继承。

The compiler is not so much accepting an interface as an argument, but rather a reference to an object that happens to implement the interface. 编译器不是接受接口作为参数,而是接受对实现接口的对象的引用 Consider the following code snippet similar to yours, and the output. 请考虑以下与您类似的代码段和输出。 You'll see in both cases the output is the Box object. 在两种情况下,您都会看到输出是Box对象。 The parameter (or "thing") being passed in both cases to println() is the very same Box object. 在两种情况下传递给println()的参数(或“事物”)都是相同的Box对象。 It's just that in one case it's being referred to as a concrete instantiation of Box, and in the other it's being referenced as an object that implements the A interface. 只是在一种情况下,它被称为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);
    }
}

The output is: 输出是:

Box@19e0bfd 箱@ 19e0bfd

Box@19e0bfd 箱@ 19e0bfd

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM