嘚儿驾...

抽象类和接口

​     抽象类和接口都是为了将方法进行抽象,然后让子类去实现,所以定义抽象方法就是两者第一个相同点

​     这种父类是没有必要去创建实例对象的,所以它们第二个相同点就是不能创建本类对象,只能由子类去实例化对象。

​      两者最明显的差异点,就是子类要扩展它们时,对抽象类用的是 extends 关键字,我们称之为继承,接口用的是 implements 关键字,我们称之为实现,这是关键字和称呼的不同,本质都一样,抽象类可以去实现接口,接口只能继承接口,不能继承类,同时,一个类最多只能继承一个父类,但可以实现多个接口,所以当我们发现既可以用抽象类,又可以用接口的时,尽量去使用接口,这样灵活度会更高。

​      抽象类更进一步抽象就诞生了接口,接口比抽象类更纯粹,没有成员属性,只有方法,子类实现接口后,唯一能做的就是重写方法,不像抽象类,子类继承抽象类之后,连带着将父类的成员属性,连带着将父类的成员属性也继承过来了,这里就是两者的又一差异点,

​     抽象类可以定义成员属性,而接口不能定义成员属性,只能定义静态属性,而且只能用 final 关键字,定义静态常量,不能定义静态变量,接口除了成员属性外还没有构造器,可以说是非常纯粹了,说白了,接口是只有方法和静态常量的类。

抽象类不能被实例化,还要个构造器做什么?

它的用处就是:限定子类的构造行为。

​ 抽象类可以将构造器,定义好几个参数,子类要想实例化则必须,想办法传入这几个参数才行。

版本差异:

​      其实接口在 JDK1.8 之前更加的纯粹,那时接口只能定义抽象方法,不能自己实现方法,不能定义静态方法,到了 Java8 才可以定义静态方法,以及可以用 default 关键字来实现方法。

public interface Runnable{
    void run();
    
    default void defaultMethod(){
        System.out.println("default 方法");
    }
    
    static void staticMethod(){
        System.out.println(" 静态方法");
    }
}

为啥在 java 8 加了这个特性呢?

​ 因为java8许多原有的接口,新增了很多的方法,这些新增的方法会影响到之前的子类,

​ 如果你继承了某个接口,突然接口新增了一个方法,而你没有去实现,你的子类就会编译失败,为了保证向下兼容性,java8 就退出了 default 关键字,被default 关键字修饰的方法,就不是抽象方法了,也就不会强制要求,已有的子类去实现方法,default 方法出现后,大家发现还挺好用!

public interface Runnable {
    void run();
    
    default void defaultMethod() {
        privateMethod(); 
        privateMethod();
        privateMethod();
    }
    private void PrivateMethod() {
     System.out.println("私有方法")   
    }
}

​ 就大量在接口中,去实现一些默认逻辑,可是一个方法中实现复杂逻辑,就会导致代码难以维护,于是 java9又推出了一个新特性,那就是能在接口中,定义private方法,这样就可以将一些内部逻辑拆开。

​ 可以发现越到后面,抽象类和接口的差异就越来越小,

那什么时候该用抽象类,什么时候该用接口?

很好判断,当你需要让子类继承成员变量,或者需要控制子类的实例化,否则你就用接口,

抽象类(abstract class) 接口(interface)
定义 包含抽象方法的类 主要是抽象方法和静态常量的类
组成 构造器
抽象方法
普通成员方法,成员变量
静态方法,静态常量
常量
静态常量
抽象方法
default 方法 ,静态方法 (Java 8)
私有方法(Java 9)
使用 子类继承抽象类(extends) 子类实现接口(implements)
关系 子类只能继承一个抽象类
抽象类可以实现多个接口
子类可以实现多个接口
接口不能继承类,但可以继承多个接口
选择 如果要继承父类的成员变量,或者需要控制子类的实例化,则选抽象类 优先选择接口,避免单继承的局限

接口实例化

1、接口不能直接实例化对象

​      学习接口时就知道它与类的区别:接口不能用于实例化对象。但是可以在 Java 中,使用接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

public interface TestInterface{}
TestInterface testInterface = new TestInterface();//这种肯定是不允许的 

2、实现接口的子类可以通过创建对象赋值给接口

​     接口不能实例化,用接口的实现类可以实例化,将实现类的对象在内存中的地址指向接口,这个接口就可以使用了。 父类引用指向子类对象。

public interface Anim{}
public class Cat implements Anim {}
Anim  anim= new Cat(); //这种是可以的,声明变量被绑定在一个以此接口实现的对象

List, Set, Map 都是接口,使用时先实现,List list = new ArrayList<>();

    接口可以被声明出来,但决不能实例化,它可以作为子类的句柄指向子类的实例。

3、子类创建对象赋值给接口后,接口再赋值给子类需要强制转换

Anim  anim= new Cat();
Cat  cat=(Cat)anim;
posted @   走马!  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示