Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 子类能否从与接口无关的父类继承接口实现_Java_Polymorphism - Fatal编程技术网

Java 子类能否从与接口无关的父类继承接口实现

Java 子类能否从与接口无关的父类继承接口实现,java,polymorphism,Java,Polymorphism,这是一种古怪的情况。考虑这个例子: interface I { void foo(); } class B { public void foo() {} } class C extends B implements I {} 使用我的编译器(Linux中的OpenJDK),它可以编译并执行以下工作: I c = new C(); c.foo(); 为什么??它是有意的,并且有语言标准的支持吗?运行时如何知道先从I向下到C,然后从C向上到B?虽然在B实现I的情况下这一点很清

这是一种古怪的情况。考虑这个例子:

interface I {
    void foo();
}

class B {
    public void foo() {}
}

class C extends B implements I {}
使用我的编译器(Linux中的OpenJDK),它可以编译并执行以下工作:

I c = new C();
c.foo();
为什么??它是有意的,并且有语言标准的支持吗?运行时如何知道先从
I
向下到
C
,然后从
C
向上到
B
?虽然在
B实现I
的情况下这一点很清楚,但考虑到
B
I

无关,这似乎是违反直觉的,它并不像您所想的那样“遵循”
C
B
继承所有非私有方法,
C
可以用这些方法做任何事情;重写它们,使用它们实现接口(如果方法是
public
),调用它们,等等


因此,方法
foo
C
的方法,即使它是从
B
继承而来的。一个类可以通过
接口
公开它的任何公共方法。首先要注意的是
扩展B和实现I的共同效果。java中的常见效果或明显结果是,您只能有一个具有特定名称、数据类型和参数的
方法(类型相同,数量相同)

任何具有相同名称和不同参数数的方法都属于方法重载。但是在您的例子中,非常简单的是,您需要在一个具体的子类中实现和定义Abstract方法
foo()

重新定义超类中的每个方法不是强制性的,但在实现接口时,它成为强制性的。因此Java认为
类C
中的
方法foo()
是从
接口I
继承的方法。否则,您将看到一个错误,要求您重新定义从接口继承的
方法foo()

不知不觉,当你考虑超类<代码> B/COD>时,这也成为方法重写的一个例子。由于

C
中的
foo()
方法具有与
B
I
中相同的声明类型(它应该根据标准、规则和实现接口的规则进行声明),因此它很容易满足接口并重写
B
中的方法

在您的例子中,您还重写了类
B
中的方法
foo()

因此,一个条件以及一个补充提议(压倒一切)正在得到满足

最后,
class C
只有一个
foo()
方法,它覆盖了
B
中的方法,并且满足
实现接口I
的条件

例如:

将方法
foo()
定义为(在
C
中):

C
中创建2个对象,如下所示:

B b=new C();
C c=new C();
调用
foo()

输出:两次打印
Hello


结论:
C
中的
foo()
满足了接口(未发现错误),并且覆盖了
B
中的
foo()
方法。在您提到的
C
示例中,是
类C
实例。因此,它需要有自己的方法
foo()

现在,C已经从
B
foo()
获得了所有公共(和默认?)方法,由于
B
,恰好是(技术上)存在的方法。因此,放置在
C
上的接口有自己的
foo()
方法的要求通过
B
s
foo()
实现

我不认为从I到C的向下和从C到B的向上是相关的,就像你提到的那样

编辑:

所有证据都表明编译器手头有一个已实现函数的列表,这些函数都位于给定类中,并且是从父类扩展而来的“虚拟”函数


因此,如果前面提到的类正在实现某些接口,则扩展函数和类自己的函数都会与需要实现的函数(因为接口)进行比较。

当您编写
时,类C扩展B实现I
将从以下位置发生:

类C从其直接超类继承超类的所有具体方法m(静态和实例),对于这些方法,以下所有条件均为真:

  • m是C的直接超类的一个成员
  • m是公共的、受保护的,或者在与C相同的包中声明了包访问权
  • C中声明的任何方法的签名都不是m签名的子签名(§8.4.2)
类C从其直接超类和直接超接口继承所有抽象和默认(§9.4)方法m,对于这些方法,以下所有条件均成立:

  • m是C的直接超类或直接超接口D的成员

  • m是公共的、受保护的,或者在与C相同的包中声明了包访问权

  • C中声明的任何方法的签名都不是m签名的子签名(§8.4.2)

  • C从其直接超类继承的具体方法没有签名是m签名的子签名

  • 不存在作为直接超类成员的方法m'或C的直接超接口D'(m不同于m',D不同于D'),因此m'来自D'重写方法m的声明


所以它继承了
接口I
的抽象方法和
类B

的具有相同签名的具体方法。你是说接口I
@DebosmitRay谢谢..更正了它。正确吗
B b=new C();
C c=new C();
b.foo();
c.foo();