【JAVA】接口中的default和static方法

发布于:2021-11-27 21:32:16

接口中方法都为抽象方法。



这句话在JAVA8之前是对的,在JAVA8之后就错了



传统的理解是接口只能是抽象方法。但是程序员们在使用中,发现很不方便,实现接口必须重写所有方法,很麻烦。所以java设计者妥协了,在java8中,支持default和static方法,这样,实现接口时,可以选择不对default修饰的方法重写。


概念:

    接口提供一个默认实现的方法,并且不强制实现类重写此方法

    默认方法使用default关键字来修饰

    default修饰方法只能在接口中使用,在接口种被default标记的方法为普通方法,可以直接写方法体。

    接口中支持定义静态方法,将关键字换成static即可


如果是Java 7,那么接口中可以包含的内容有:
1. 常量
2. 抽象方法

如果是Java 8,还可以额外包含有:
3. 默认方法default
4. 静态方法static

如果是Java 9,还可以额外包含有:
5. 私有方法

接口的默认方法


从Java 8开始,接口里允许定义默认方法。
格式:
public default 返回值类型 方法名称(参数列表) {
方法体
}

备注:接口当中的默认方法,可以解决接口升级的问题。

接口的静态方法


从Java 8开始,接口里允许定义静态方法。
格式:
public interface InterfaceA {
/**
* 静态方法
*/
static void showStatic() {
System.out.println("InterfaceA++showStatic");
}
}


注意,实现接口的类或者子接口不会继承接口中的静态方法


特点
默认方法可以不强制重写,并且在一个类继承接口后可以直接使用接口中的默认方法

继承类可以直接使用接口中的static方法,也可以创建对象后使用接口中的default方法



interface InterfaceA // 定义一个接口
{
default public void otherprint() // 带方法体的默认方法
{
System.out.println("print default1 methods InterfaceA!");
}
}

class subClass implements InterfaceA //子类InterfaceAB实现接口InterfaceA
{

}

public class Interfacedefault
{
public static void main(String[ ] args)
{
subClass subObj = new subClass( ); //实例化子类对象
subObj.otherprint( ); //调用接口中的默认方法

InterfaceA InterfaceAobj = new subClass(); // 实例化子类对象,赋值给一个接口引用
InterfaceAobj.otherprint( ); //调用接口中的默认方法
}
}

输出:

注意如果是static静态方法,类继承接口后不可以直接用,也就是上方的default改为static 就会出错








当一个类实现多个接口时,若多个接口中存在相同默认方法(方法名、参数、返回值相同),此时实现类必须要重写默认方法,否则编译错误

Java中只能继承一个类,但是可以实现多个接口,当多个接口中有同一个方法时,以前是没问题的,因为实现类必须重写方法。但现在,当多个接口中有同一个用default修饰的方法时,就无法判断到底实现的是哪个接口的方法。这种情况下,就必须重写方法。



重写有两种实现方法:


实现类中自己重写默认方法实现类使用super关键字指定使用哪个接口的默认方法

interface TestInterface1 //定义接口1
{
default void test()
{
System.out.println("TestInterface1");
}
}

interface TestInterface2 //定义接口2
{
default void test()
{
System.out.println("TestInterface2");
}
}


方法1:


class Test implements TestInterface1, TestInterface2
{
@Override
public void test()
{
System.out.println("这是重写的方法");
}
}

public class test{
public static void main(String[ ] args)
{
Test TestsubObj = new Test ( ); //实例化子类对象
TestsubObj .test( ); //调用接口中的默认方法
}
}

输出:


方法2:


public class Test implements TestInterface1, TestInterface2
{
@Override
public void test()
{
// 调用TestInterface1接口的默认test()方法
TestInterface1.super.test();
}
}

public class test{
public static void main(String[ ] args)
{
Test TestsubObj = new Test ( ); //实例化子类对象
TestsubObj .test( ); //调用接口中的默认方法
}
}

输出:



当然,如果A和B的默认方法不同, 实现类C则会隐式继承了两个默认方法






如果子类继承父类,父类中有A方法,该子类同时实现的接口中也有A方法,那么子类会继承父类的b方法而不是继承接口中的b方法

子类优先继承父类的方法, 如果父类没有相同签名的方法,才继承接口的默认方法。



接口A


interface InterfaceA // 定义一个接口
{
default public void test() // 带方法体的默认方法
{
System.out.println("print default1 methods InterfaceA!");
}
}

类B:


public class B {
public void test()
{
System.out.println("print Class B");
}
}

类Test 继承类B和接口A


class Test extends B implements InterfaceA{

}

新建一个Test对象,调用test方法 为类B中的方法


实现类中如果重写了接口的default 默认方法 那么 实例化子类对象,赋值给接口引用之后,还是使用重写的默认方法

一个实现了接口的类的对象赋给接口的引用,
“一个接口,多个方法”,展示了Java的动态多态性。
java可以父类引用子类,体现了java的多态性,但是不能子类引用父类,可以从上往下,不可以从下往上



interface InterfaceA // 定义一个接口
{
default void otherprint() // 带方法体的默认方法
{
System.out.println("print default1 methods InterfaceA!");
}
}

class subClass implements InterfaceA //子类InterfaceAB实现接口InterfaceA
{
public void otherprint() // 带方法体的默认方法
{
System.out.println("实现类重写的方法");
}

}

public class trival{
public static void main(String[ ] args)
{
subClass subObj = new subClass( ); //实例化子类对象
subObj.otherprint( ); //调用接口中的默认方法

InterfaceA InterfaceAobj = new subClass(); // 实例化子类对象,赋值给一个接口引用
InterfaceAobj.otherprint( ); //调用接口中的默认方法
}
}

输出:



相关推荐

最新更新

猜你喜欢