默认方法:

为什么引入默认方法?

如何使用?

默认方法带来的问题以及解决方法

1.在定义接口时,我们声明了一系列方法,而方法的实现是通过接口的实现类来完成的,接口的出发点是站在顶层考虑问题,对于一个有着很悠久历史的接口来说,如果它有着很多实现类,当想在接口中增加一个功能,当然对于顶层接口来说so easy,但这对于众多的实现类以及已经将接口应用于实际项目中的人员来说,就有点麻烦了,因为每个实现类都要为新增的方法提供根据自己需求的具体实现,同时如果接口的api已经公示出去,则对于使用者,以及在原来接口上提供了具体实现的厂商来说,要么继续使用旧的接口,不做改动,要么实现新的接口,又因为不同的厂商是根据旧的接口来实现自己的业务,所以对于业务的改动可以说是牵一发而动全身,疼啊。。。

因此,为了解决这个问题,Java8提出了默认方法,同时也允许在接口中声明静态方法。

2.默认方法可以指定接口方法的默认实现,即接口能够提供方法的具体实现,因此,如果实现接口,不显式的提供该方法的具体实现,就会自动继承默认的实现。

默认方法由default修饰符修饰,并像类中声明的其他方法一样包含方法体。

interface AClass{
	default void hello() {
		System.out.println("i \' am A class");
	}
}

3.java没有多继承,但是一个类可以继承多个接口,就相当于实现了多继承的问题,下面我们为了方便,全部用多继承来说明问题,如果一个类继承了多个类,而这写父类中又有相同的函数签名,当子类调用父类中的相同的函数签名时,具体执行哪个方法了???

要解决这个问题,必须遵循以下三个规则:

⑴类中的方法优先级最高,类或者父类中声明的方法的优先级高于任何声明为默认方法的优先级

⑵如果无法依据第一条进行判断,则子接口的优先级更高:函数签名相同的时候,优先选择拥有最具体实现的默认方法的接口,

⑶如果还是无法判断,继承了多个接口的类必须通过显示覆盖和调用期望的方法;

下来用实际例子说明:

interface AClass{
	default void hello() {
		System.out.println("i \' am A class");
	}
}

class BClass implements AClass{
	 public void hello() {
		System.out.println("i \' am B class");
	}
}
class CClass extends BClass implements AClass{
	public static void main(String[] args) {
		new CClass().hello();
	}
}

输出结果为:i ' am B class

解析:根据第二条规则,B实现A接口,C继承B,实现A,应该选择提供更具体实现的默认方法的接口,即B比A更具体,所以输出B的hello()方法;

interface DClass{
	default void hello() {
		System.out.println("i \' am D class");
	}
}
class EClass implements AClass{
	 public void hello() {
			System.out.println("i \' am E class");
		}
}
class FClass extends BClass implements AClass ,DClass{
	public static void main(String[] args) {
		new FClass().hello();
	}
}

输出结果是: i  ' am B class ,原理同上。

class GClass  implements AClass ,DClass{
	public static void main(String[] args) {
		new GClass().hello();
	}
}

根据规则,A,D平行关系,无法判断,则必须显式的覆盖hello方法;

因此,这个类会报错,同时iDE会提示:

Java 调整接口异常错误等级 java接口冲突_优先级

菱形继承问题:

interface HClass extends AClass{}
interface IClass extends AClass{}

class JClass implements HClass ,IClass{
	public static void main(String[] args) {
		new JClass().hello();
	}
}

因为只有AClass声明了一个默认方法,所以结果是 A class

如果HClass 也提供了默认的hello方法,则根据规则(2),则会输出 H的hello方法。