抽象类和接口总结

目录

一、抽象类

1、为啥需要抽象类?

2、抽象类有什么特征?

3、面向抽象类编程

二、接口

1、为啥需要接口?

2、实现接口

3、接口可以继承接口

4、继承关系

5、接口中的默认方法 - default

抽象类和接口的对比


一、抽象类

本质上是定义接口规范:即规定高层类的接口,从而保证所有子类都有相同的接口实现,这样,多态就能发挥出威力。

1、为啥需要抽象类?

抽象方法

1、为了实现多态,如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法;

2、把一个方法声明为abstract,表示它是一个抽象方法,本身没有实现任何方法语句。因为这个抽象方法本身是无法执行的,所以,定义类抽象方法的类也无法被实例化。编译器会告诉我们,无法编译类,因为它包含抽象方法

 

2、抽象类有什么特征?

抽象类:

1、如果一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract修饰。

2、因为无法执行抽象方法,因此这个类也必须申明为抽象类(abstract class)。

3、使用abstract修饰的类就是抽象类。抽象类无法实例化;

4、子类继承抽象类,必须重写抽象方法,但是不一定对所有抽象方法完全重写

凡是实现类必须要完整的重写所有的方法。(实现类!)部分不重写的话子类只能也是抽象类。。直至。。。。所有抽象方法被全部重写为止。

 

3、面向抽象类编程

1、面向抽象编程的本质就是:

  • 上层代码只定义规范(例如:abstract class Person);

  • 不需要子类就可以实现业务逻辑(正常编译);

  • 具体的业务逻辑由不同的子类实现,调用者并不关心。

2、实例:

当我们定义了抽象类Person,以及具体的StudentTeacher子类的时候,我们可以通过抽象类Person类型去引用具体的子类的实例:

Person s = new Student();
Person t = new Teacher();

这种引用抽象类的好处在于,我们对其进行方法调用,并不关心Person类型变量的具体子类型:

// 不关心Person变量的具体子类型:
s.run();
t.run();

同样的代码,如果引用的是一个新的子类,我们仍然不关心具体类型:

// 同样不关心新的子类是如何实现run()方法的:
Person e = new Employee();
e.run();

这种尽量引用高层类型,避免引用实际子类型的方式,称之为面向抽象编程。

 

二、接口

1、为啥需要接口?

还是为了实现多态,和抽象类的主要区别是:接口中连字段都没有,所有方法都是抽象方法,并且声明的类型默认为 public abstract。

2、实现接口

当一个具体的class去实现一个interface时,需要使用implements关键字。举个例子:

class Student implements Person {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(this.name + " run");
    }

    @Override
    public String getName() {
        return this.name;
    }
}

我们知道,在Java中,一个类只能继承自另一个类,不能从多个类继承(单继承)。但是,一个类可以实现多个interface(多实现,例如:

class Student implements Person, Hello { // 实现了两个interface
    ...
}

3、接口可以继承接口

一个interface可以继承自另一个interfaceinterface继承自interface使用extends,它相当于扩展了接口的方法。例如:

interface Hello {
    void hello();
}

interface Person extends Hello {
    void run();
    String getName();
}

此时,Person接口继承自Hello接口,因此,Person接口现在实际上有3个抽象方法签名,其中一个来自继承的Hello接口。

4、继承关系

合理设计interfaceabstract class的继承关系,可以充分复用代码。一般来说,公共逻辑适合放在abstract class中,具体逻辑放到各个子类,而接口层次代表抽象程度。可以参考Java的集合类定义的一组接口、抽象类以及具体子类的继承关系:

┌───────────────┐
│   Iterable    │
└───────────────┘
        ▲                ┌───────────────────┐
        │                │      Object       │
┌───────────────┐        └───────────────────┘
│  Collection   │                  ▲
└───────────────┘                  │
        ▲     ▲          ┌───────────────────┐
        │     └──────────│AbstractCollection │
┌───────────────┐        └───────────────────┘
│     List      │                  ▲
└───────────────┘                  │
              ▲          ┌───────────────────┐
              └──────────│   AbstractList    │
                         └───────────────────┘
                                ▲     ▲
                                │     │
                                │     │
                     ┌────────────┐ ┌────────────┐
                     │ ArrayList  │ │ LinkedList │
                     └────────────┘ └────────────┘

在使用的时候,实例化的对象永远只能是某个具体的子类,但总是通过接口去引用它,因为接口比抽象类更抽象

List list = new ArrayList(); // 用List接口引用具体子类的实例
Collection coll = list; // 向上转型为Collection接口
Iterable it = coll; // 向上转型为Iterable接口

5、接口中的默认方法 - default

在接口中,可以定义default方法。例如,把Person接口的run()方法改为default方法:

public class Main {
    public static void main(String[] args) {
        Person p = new Student("Xiao Ming");
        p.run();
    }
}

interface Person {
    String getName();
    default void run() {
        System.out.println(getName() + " run");
    }
}

class Student implements Person {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

 Run

 

抽象类和接口的对比

 抽象类 abstract class接口 interface(比抽象类更抽象)
继承只能extends一个class,单继承可以implements多个interface,多实现
字段可以定义实例字段不能定义实例字段
抽象方法可以定义可以定义
非抽象方法可以定义非抽象方法

可以定义default方法 + java8可以在接口中定义静态方法:参考文章

https://zhuanlan.zhihu.com/p/28250933

实例化不可不可
构造函数

抽象类可以有构造器

参考:https://www.jianshu.com/p/93d701282bd9

成员数据 final static
成员方法public  abstractpublic abstract

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值