默认方法
Java 8中允许接口中包含具有具体实现的方法,该方法称为 “默认方法”,默认方法使用 default 关键字修饰。
一个例子
/**
* @author black猫
* @date 2019-11-27
* 一个接口
*/
public interface MyInterface<T> {
/***
* sayHi 抽象方法
* @param name
* @return
*/
T sayHi(String name);
/***
* sayHello 默认方法
* @param name
* @return
*/
default String sayHello(String name) {
return "Hello :" + name;
}
}
/**
* @author black猫
* @date 2019-11-28
* 实现类
*/
public class MyInterfaceImpl implements MyInterface<String> {
/***
* sayHi 方法
* @param name
* @return
*/
@Override
public String sayHi(String name) {
return "Hi :" +name;
}
}
/***
* @author black猫
* @date 2019-11-27
* 接口的实现类 测试
*/
public class MyInterfaceTest {
/***
* 测试默认方法
*/
@Test
public void test01() {
MyInterface myInterface = new MyInterfaceImpl();
// MyInterfaceImpl类并没有实现 sayHello 方法就可以调用 MyInterface接口的静态方法
System.out.println(myInterface.sayHello("Tom"));
// Hello :Tom
System.out.println(myInterface.sayHi("Jim"));
// Hi :Jim
}
}
默认方法的重写,修改MyInterfaceImpl
/**
* @author black猫
* @date 2019-11-28
* 实现类
*/
public class MyInterfaceImpl implements MyInterface<String> {
/***
* sayHi 方法
* @param name
* @return
*/
@Override
public String sayHi(String name) {
return "Hi :" +name;
}
/***
* sayHello 默认方法
* @param name
* @return
*/
@Override
public String sayHello(String name) {
return "hello: "+name+" by MySuperClass...";
}
}
/**
* @author black猫
* @date 2019-11-27
* 接口的实现类 测试
*/
public class MyInterfaceTest {
/***
* 测试
*/
@Test
public void test01() {
MyInterface myInterface = new MyInterfaceImpl();
System.out.println(myInterface.sayHello("Tom"));
// hello: Tom by MySuperClass...
System.out.println(myInterface.sayHi("Jim"));
// Hi :Jim
}
}
默认方法的继承
默认的方法也可以被继承
/**
* @author black猫
* @date 2019-11-27
* 接口的实现类 测试
*/
public class MyInterfaceTest {
@Test
public void test02() {
new Interface02(){}.printHello();
// Interface01 hello!
new Interface03(){}.printHello();
// Interface03 hello!
new Interface04(){
@Override
public void printHello() {
System.out.println("Interface04 hello!");
}
}.printHello();
// Interface04 hello!
}
}
// Interface01接口里面有一默认方法
interface Interface01 {
default void printHello() {
System.out.println("Interface01 hello!");
}
}
/***
* Interface02 继承 Interface01 默认方法被继承
*/
interface Interface02 extends Interface01 {
}
/***
* Interface03 继承 Interface01 默认方法继承后重写默认方法
*/
interface Interface03 extends Interface01 {
@Override
default void printHello() {
System.out.println("Interface03 hello!");
}
}
/***
* Interface04 继承 Interface01 默认方法继承后重新定义为抽象方法
*/
interface Interface04 extends Interface01 {
@Override
void printHello();
}
默认方法的多继承
当接口的默认方法有冲突时,需要自己重写调用方法,也可以使用 InterfaceName.super.methodName(); 的方式手动调用需要的接口默认方法。
// Interface05接口有一个默认方法 printHello
interface Interface05 {
default void printHello() {
System.out.println("Interface05 hello!");
}
}
// Interface06接口有一个默认方法 printHi
interface Interface06 {
default void printHi() {
System.out.println("Interface06 hi!");
}
}
// Interface07接口有两个默认方法 printHello 和 printHi
interface Interface07 {
//默认方法 printHello
default void printHello() {
System.out.println("Interface07 hello!");
}
//默认方法 printHi
default void printHi() {
System.out.println("Interface07 hi!");
}
}
// Class08 继承 Interface05和Interface06
class Class08 implements Interface05, Interface06 {
}
// 报错 Class09 继承 Interface06和Interface07
// 默认方法printHi冲突 必须选择重写一个父类的printHi
//class Class09 implements Interface06, Interface07 {
//
//}
// Class10 继承 Interface06和Interface07
// 默认方法冲突 选择一个重写
class Class10 implements Interface06, Interface07 {
@Override
public void printHi() {
//覆写存在歧义的方法,可以使用 InterfaceName.super.methodName(); 的方式手动调用需要的接口默认方法。
Interface06.super.printHi();
Interface07.super.printHi();
System.out.println("Class10 hi!");
}
}
接口和抽象类(类优先原则)
当接口继承行为发生冲突时,类的方法声明优先于接口默认方法,无论该方法是具体的还是抽象的。
/**
* @author black猫
* @date 2019-11-28
*
*/
public class AbstractTest {
public static void main(String[] args) {
Class001 class001 = new Class001();
class001.printHello();
// hello interface01...
class001.printHi();
// hi abstract01...
}
}
// 继承抽象类Abstract001 并且实现接口Interface001
class Class001 extends Abstract001 implements Interface001 {
@Override
public void printHello() {
Interface001.super.printHello();
}
}
// 一个接口有两个默认方法
interface Interface001 {
default void printHello() {
System.out.println("hello interface01...");
}
default void printHi() {
System.out.println("hi interface01...");
}
}
//一个抽象类 有一个抽象方法 一个实现的方法
abstract class Abstract001 {
abstract void printHello();
public void printHi() {
System.out.println("hi abstract01...");
}
}
接口的静态方法
接口的静态方法和类的静态方法使用一致
/**
* @author black猫
* @date 2019-11-28
* Java 8 还在允许在接口中定义静态方法。
*/
public class StaticTest {
public static void main(String[] args) {
Interface.printHelloWorld();
}
}
/**
* Interface接口有一个静态方法 printHelloWorld
*/
interface Interface {
/***
* 静态方法
*/
static void printHelloWorld() {
System.out.println("Interface11 printHelloWorld...");
}
}
我的小结
java8的接口默认方法降低了实现类之间的耦合,当需要为一个接口添加方法时,不必对所有实现类都修改。可以为接口添加新的默认方法,而不会破坏已有的接口的实现,也为升级旧接口且保持向后兼容提供了新的途径。
文章首发于黑猫のBlog欢迎来留言啊!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。