接口与抽象类

接口

接口:接口是对行为的抽象。
在java中,接口不提供具体的实现,它仅仅是描述了某些事物的共同具有的功能的抽象,并非具体实现。
例如:人和猫都是生物,都需要进食和休息,那么就可以描述一个名为生物的接口,将进食和休息的行为抽象的描绘出来,再由人和猫分别实现生物这个接口,根据他们特有的进食和休息方式,去实现这个抽象行为的具体细节。

接口的特征(jdk8以前)

1.接口中所有方法不能有具体实现,即所有方法都必须为抽象方法,不能有方法体,方法修饰默认为public abstract(可省略);

2.接口中不能定义实例变量,非抽象实例方法,静态方法(jdk8以前);

3.接口没有构造方法,也不能被实例化;

4.接口中声明的成员变量都是public static final修饰的,必须显式的初始化;

5.接口中不能实现接口,但是可以多继承;

在这里插入图片描述
6.接口需要通过子类来实现他的抽象方法;
接口:

public interface InterfaceDIY {
    public static final int a = 1234;//全局变量:默认为public static final修饰的变量
    int fun();//方法默认为public abstract修饰
    //接口中的方法不能有方法体(jdk8以前,可认为接口所有方法都是抽象方法)
}

实现类:

public class test extends AbstractDIY implements InterfaceDIY {
    @Override
    public int fun() {
        return 0;
    }
}

7.如果一个类无法实现接口中的所有方法,这个类该设计为抽象类,即并非所有类都必须实现接口所有方法(抽象类)。

public abstract class AbstractDIY implements InterfaceDIY {
//抽象类并非必须实现fun方法
}

8.不允许创建接口的实例,但是可以定义接口类型的引用变量,引用实现该接口类的实例。

public static void main(String[] args) {
        InterfaceDIY interfaceDIY=new InterfaceDIY() {
            @Override
            public int fun() {
                return 0;
            }
        };
        interfaceDIY.fun();
    }

9.接口中的方法发生改变,其子类也需进行相对的改变(jdk8以前)
在接口中添加print方法。

public interface InterfaceDIY {
    public static final int a = 1234;//全局变量:默认为public static final修饰的变量
    //jdk8以前
    int fun();//方法默认为public abstract修饰
    //接口中的方法不能有方法体
    int print();//新添加了print方法
}

实现类需要再次实现print方法,否则编译异常。

在这里插入图片描述

public class test  implements InterfaceDIY {
    @Override
    public int fun() {
        return 0;
    }

    @Override
    public int print() {
        return 0;
    }
}

接口在jdk8中的新特性

jdk8后接口可使用默认方法和静态方法。

jdk8新特性参考:https://mp.weixin.qq.com/s?src=11&timestamp=1604888589&ver=2695&signature=sSjp1ZoOE-uy9-TpZFGn4Ol6hyAbw9cUUPAwgy0kfd7hsSRpKILZ5iRPKNGuZUpjYVXY8bSC3K4Lyi7qcTvF-2c3iDg7a2lLlJyP4dsQLC8oO9HZaFRyAYIqExje3h&new=1

1.默认方法(default)
默认方法使得开发者可以在 不破坏二进制兼容性的前提下,往现存接口中添加新的方法,即不强制那些实现了该接口的类也同时实现这个新加的方法。
接口:添加了默认方法deffun()

public interface InterfaceDIY {
    public static final int a = 1234;//全局变量:默认为public static final修饰的变量
    //jdk8以前
    int fun();//方法默认为public abstract修饰
    //接口中的方法不能有方法体
    public static void main(String[] args) {
    }
    default void deffun() {//默认方法
        System.out.println("def");
    }
}

实现类:创建接口引用可直接调用

 InterfaceDIY interfaceDIY=new InterfaceDIY() {
            @Override
            public int fun() {
                return 0;
            }
        };
        interfaceDIY.deffun();

默认方法和抽象方法之间的区别在于抽象方法需要实现,而默认方法不需要。接口提供的默认方法会被接口的实现类继承或者覆写。

尽管默认方法有这么多好处,但在实际开发中应该谨慎使用:在复杂的继承体系中,默认方法可能引起歧义和编译错误。

情景题:若是实现类实现了两个接口,两个接口同时实现了一个默认方法,实现类如何分辨需要实现哪个接口下的默认方法?
答:这种情况下,编译系统会要求实现类覆盖这个默认方法,对该默认方法进行重写。

另一个接口:定义一个与第一个接口相同的方法deffun()

public interface InterfaceDIY1 {
    default void deffun() {
        System.out.println("def1");
    }
}

实现类:重写该默认方法

public class test implements InterfaceDIY,InterfaceDIY1 {
    @Override
    public int fun() {
        return 0;
    }

    @Override
    public void deffun() {
        System.out.println("childdef");
    }
}

2.静态方法
直接用接口调用这些静态方法

    public static void main(String[] args) {
        InterfaceDIY.stafun();
    }

jdk8中,接口中可定义main()方法,并编译运行

public interface InterfaceDIY {
    public static final int a = 1234;//全局变量:默认为public static final修饰的变量
    //jdk8以前
    int fun();//方法默认为public abstract修饰
    //接口中的方法不能有方法体
    public static void main(String[] args) {
        System.out.println("运行main方法");
    }
    default void deffun(){
        System.out.println("def");
    }

    static void stafun(){
        System.out.println("sta");
    }
}

运行结果如下:
在这里插入图片描述

使用接口的原因

1.接口被用来描述一种抽象;
2.接口可用来实现解耦;
3.Java通过实现接口来实现多继承;
4.抽象类内部可能包含非final的变量,但是在接口中存在的变量一定是final,public,static的。

抽象类

抽象类可以理解为:没有足够的信息描绘一个完整的对象而存在的类。

抽象类的特征

1.抽象类不能直接实例化为具体对象,必须通过其他类继承才能使用,或者使用子类进行向上转型实现抽象类的实例化;

2.一个类只能继承一个抽象类,通过在类名后加extends继承;

3.抽象类的修饰符不能是private和final;

4.抽象类不一定有抽象方法,但是有抽象方法的类一定是抽象类(和接口);

5.抽象类可以有构造方法,但是不能直接实例化为对象,构造方法可以用来初始化抽象类内部声明的通用变量,抽象类的子类隐含父类的构造方法;

public abstract class AbstractDIY {
    AbstractDIY() {
    }
}

6.抽象类的子类需给出抽象类中抽象方法的具体实现,除非该子类也是抽象类。
抽象类:内含抽象方法abs()

public abstract class AbstractDIY {
    AbstractDIY() {
    }
    abstract void abs();
}

实现类:若是抽象类,则非必须实现抽象方法

public class test extends AbstractDIY{
    @Override
    void abs() {
        System.out.println("抽象方法");
    }
}

7.外部类抽象类不允许使用static修饰,内部类抽象类可以。

public abstract class AbstractDIY {
    AbstractDIY() {
    }
    static abstract class AbStractInside {
    }
    abstract void abs();
}

接口与抽象类的区别(jdk8以前)

  1. 方法实现:抽象类可以有方法的具体实现,而接口只有抽象方法,不能有具体实现;
  2. 子类继承方面:实现抽象类使用extends关键字来继承抽象类,实现接口使用的是implements;
    3.继承: 一个类只能继承一个抽象类,但一个类却可以实现多个接口;
  3. 构造方法:抽象类可以有构造器,接口不可以有构造器;
  4. 方法修饰符:接口方法默认修饰符是public,而抽象方法可以使用public、protected和default等
  5. 增加新方法对子类的影响:抽象类添加默认方法无需修改子类,接口只能添加抽象方法,所以子类也需要进行改变;
  6. 静态修饰符:接口不能含有静态代码块和静态方法,抽象类可以;
  7. 成员变量:抽象类的成员变量可以是各种类型,而接口的成员变量只能是由public static final修饰的;
  8. main方法:抽象类可以有main方法,而且可以运行,但是接口不能定义main方法(因为不能有静态方法)。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值