关于Java中继承多接口同名方法的问题

在Java中如果一个类同时继承接口A与B,并且这两个接口中具有同名方法,会怎么样?

动手做实验:

 1 interface A{
 2     void fun();
 3 }
 4 interface B{
 5     void fun();
 6 }
 7 interface C extends A,B{
 8
 9 }
10 public class Test implements C{
11     @Override
12     public void fun() {
13         System.out.println("hehe");
14     }
15
16     public static void main(String[] args) {
17         new Test().fun();
18     }
19 }

上例的情况,可以正常编译运行,输出"hehe",因为A与B中的fun具有相同的签名(参数个数与类型相同)

 1 interface A{
 2     void fun();
 3 }
 4 interface B{
 5     int fun(int x);
 6 }
 7 interface C extends A,B{
 8
 9 }
10 public class Test implements C{
11     @Override
12     public void fun() {
13         System.out.println("hehe");
14     }
15
16     @Override
17     public int fun(int x) {
18         return 0;
19     }
20
21     public static void main(String[] args) {
22         new Test().fun();
23     }
24 }

上例也是可以编译运行的,因为A与B中的fun方法具有不同的函数签名,本质上是两个方法,分别实现即可。

 1 interface A{
 2     void fun();
 3 }
 4 interface B{
 5     int fun();
 6 }
 7 interface C extends A,B{
 8
 9 }
10 public class Test implements C{
11     @Override
12     public void fun() {
13         System.out.println("hehe");
14     }
15
16     public static void main(String[] args) {
17         new Test().fun();
18     }
19 }

而这种具有相同函数签名,但不同返回值的方法,是没有办法编译的,接口C便已经无法编译。

在Java8中,接口可以具有默认的实现,这里再举几个实例

 1 interface A{
 2     default void fun() {
 3         System.out.println("I am A");
 4     }
 5 }
 6 interface B{
 7     default void fun() {
 8         System.out.println("I am B");
 9     }
10 }
11 interface C extends A,B{
12     @Override
13     default void fun() {
14         System.out.println("I am C");
15     }
16 }
17 public class Test implements C{
18
19     public static void main(String[] args) {
20         new Test().fun();
21     }
22 }

上例将输出"I am C",因为接口C给出了fun的默认实现

 1 interface A{
 2     default void fun() {
 3         System.out.println("I am A");
 4     }
 5 }
 6 interface B{
 7     default void fun() {
 8         System.out.println("I am B");
 9     }
10 }
11 interface C extends A,B{
12     @Override
13     void fun();
14 }
15 public class Test implements C{
16     @Override
17     public void fun() {
18         C.super.fun();
19     }
20
21     public static void main(String[] args) {
22         new Test().fun();
23     }
24 }

上例将产生编译错误,因为C中对fun方法进行了覆盖,C的fun是抽象的,在第18行将产生无法访问C中抽象方法fun的编译错误。

 1 interface A{
 2     default void fun() {
 3         System.out.println("I am A");
 4     }
 5 }
 6 interface B{
 7     default void fun() {
 8         System.out.println("I am B");
 9     }
10 }
11 interface C extends A,B{
12     @Override
13     default void fun() {
14         A.super.fun();
15     }
16 }
17 public class Test implements C{
18
19     public static void main(String[] args) {
20         new Test().fun();
21     }
22 }

接口C为fun方法指定为接口A中的实现,程序输出"I am A"

参考链接:

http://stackoverflow.com/questions/2801878/implementing-two-interfaces-in-a-class-with-same-method-which-interface-method

http://www.oschina.net/translate/java-8-explained-default-methods

时间: 2024-10-24 03:10:23

关于Java中继承多接口同名方法的问题的相关文章

关于Java中继承和接口的理解

关于Java中继承和接口的理解 Java语言中,为了实现代码重用,设计了继承这一机制,但是,其设计成单继承,这样设计是有原因的,如下图: Figure1:deadly diamond of death 此图问题称为菱形问题(diamond problem),就是说,当A的子类B和C同时实现了A中的方法,则同时继承了B和C的子类D在调用该方法时会出现混乱,无法得知该调用哪一个方法. 既然不能实现多继承,我们就会考虑把很多方法就写在父类里,或者继承抽象类,实现其方法,但是,这样会导致一个问题,比如说

Java中的(构造方法、方法重载、final修饰符使用及继承和抽象)

构造方法: 构造方法的名称和类名相同,没有返回类型,参数列表(类型.个数)不同 方法重载:成员方法和构造方法都可以进行重载 方法名相同但是参数列表(类型,个数)不同,成为方法的重载. 继承:直支持单继承,一个类只能有一个父类 继承要用extends关键字修饰 public class Dog extends Pet{ //方法体 } 子类调用父类公用的成员变量和方法需使用关键字super 如super.方法名 super(成员变量,成员变量....) 方法重写: 方法重写的需求: 1.重写方法和

Java中各种(类、方法、属性)访问修饰符与修饰符的说明

类: 访问修饰符 修饰符 class 类名称 extends 父类名称 implement 接口名称 (访问修饰符与修饰符的位置可以互换) 访问修饰符 名称 说明 备注 public 可以被本项目的所有类访问(使用),其他项目若想使用本项目中的类,必须将本项目打包为jar包,然后加入到classpath中 public类必须定义在和类名相同的同名文件中 (default) 只能被同一个包中的类访问(使用) 默认的访问权限,可以省略此关键字,可以定义在和public类的同一个文件中 修饰符 名称

【翻译】JAVA中抽象类和接口的区别

不知道有没有人翻译过了,这篇是挺简单的,权当复习一遍内容吧. 很多常见的面试问题如"抽象类和接口有什么区别","你在什么时候用抽象类什么时候用接口".所以在这篇文章里面,我们会讨论一下这个话题. 在开始讨论它们的区别之前,我们先看看它们的介绍. Abstract class 抽象类 抽象类被用来抽象出子类的共同特征.它是不能被实例化的,它只能被子类继承作为超类使用.抽象类被用作它的子类下的层次结构创建模板(Abstract classes are used to c

java中抽象类与接口的区别

转自: http://blog.csdn.net/tp7309/article/details/10452445 二者的区别快忘得差不多了,从别处看到这文章感觉写的不错,正好复习复习,也给大家分享一下. 抽象类 abstract class 包含抽象方法的类,叫抽象类.而抽象的概念就是抽象出共同属性:成员变量和方法.所以抽象类可以有private等多种权限的成员变量和非abstract的成员方法.当然抽象方法是一定要有的. 抽象类是用于单一继承的,不能实例化.而继承类一定要实现抽象方法,因为抽象

我如何理解Java中抽象类和接口

在面试中我们经常被问到:Java中抽象类和接口的区别是什么? 然后,我们就大说一通抽象类可以有方法,接口不能有实际的方法啦:一个类只能继承一个抽象类,却可以继承多个接口啦,balabala一大堆,就好像把标准答案熟练的说出来一样. 抽象类和接口这篇文章讲到了他们的区别和联系,它们确实有很多相似的地方,但是从本质上看,或从语言的设计角度来看,这不是它们最本质的区别. 不卖关子,我个人对这两个的理解: 类是具体实例的抽象,比如一个json字符串的抽象:而抽象类就是类的抽象:接口就是抽象类的抽象,接口

Java 中extends与implements使用方法 (转载)

转自:http://blog.csdn.net/chen_chun_guang/article/details/6323201 初学Java语言, 代码中的extends和implements让我感到很迷惑,现在终于弄明白它们之间的区别和用法了. //定义一个Runner接口 public inerface Runner { int ID = 1; void run (); } //定义一个interface Animal,它继承于父类Runner interface Animal extend

Java中继承,类的高级概念的知识点

1. 继承含义 在面向对象编程中,可以通过扩展一个已有的类,并继承该类的属性和行为,来创建一个新的类,这种方式称为继承(inheritance). 2. 继承的优点 A.代码的可重用性 B.子类可以扩展父类的属性和方法 C.父类的属性和方法可用于子类 D.设计应用程序变得更加简单 3. 如何判断类具有继承关系? 类与类的关系:  a. has—a(组合关系) b. is—a(继承关系) 4. Java中继承的实现(关键字:extends)   关键字extends出现在类声明时的类名后,exte

Java中抽象类和接口的区别(abstract class VS interface)

前言:本文解决的问题 什么是抽象类 抽象类的应用场景 接口可以有方法实现吗 接口和抽象类的区别 1 什么是抽象类 在声明时含有关键字abstract就是抽象类,抽象类它可以看作具体类的一个模板,继承它的子类可以从抽象类中共享一些方法(可能是不完整的)和属性. A class which is declared with the abstract keyword is known as an abstract class in Java. It can have abstract and non-