目录
前言
1. 抽象类
1.1 认识抽象类
1.2 抽象类的特征
1.3 抽象类的作用
2. 接口
2.1 接口的概念
2.2 接口的语法
2.3 接口的使用
2.4 接口的特性
2.5 接口的好处
2.6 接口之间的继承
结语
前言
今天我们来讲Java中的抽象类和接口,它们在面向对象中发挥着重要的作用,解决了我们前面学习的继承的一个痛点,具体是什么呢?在这里我先买一个关子
1. 抽象类
1.1 认识抽象类
在面向对象中,所有的对象都是通过类来描述的,但是有些类却因包含的信息不足以描述出一个完整的对象,这些类我们就把它们叫做抽象类
在Java中有一个关键字叫:abstract,它的意思就是抽象。abstract修饰类,这个类就是抽象类;abstract修饰方法,这个方法就是抽象方法。要注意:抽象方法只能有方法签名,一定不能有方法体
//抽象类
public abstract class Test{
//抽象方法
public abstract void func( );
}
1.2 抽象类的特征
- 抽象类也是类,它的内部可以包含普通成员方法和成员变量,也可以有构造器
- 抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
- 抽象类不能够创建对象(就算抽象类中没有抽象方法,也不能被实例化)
- 抽象类仅作为一种特殊的父类,让子类继承并实现(因为抽象方法要被重写,所以抽象方法不能用private、final、static修饰)
- 一个类继承抽象类,就必须重写抽象类中所有抽象方法,否则这个类也必须定义成抽象类
因为Animal类无法准确描绘出一个对象,所以我们把它设置为抽象类,然后再创建一个Dog类来继承Animal,并重写Animal中的抽象方法,最后使用父类类型引用子类对象,再调用重写方法,实现多态
1.3 抽象类的作用
抽象类本身不能被实例化,只能创建一个新的类来继承抽象类,让子类重写抽象类中的抽象方法
实际上抽象类在开发中并不是必备的,但是使用抽象类就相当于多了一层校验,它可以帮我们检测是否误用为被重写的方法,支持我们更好地使用多态
2. 接口
2.1 接口的概念
接口类似我们上面讲到的抽象类,它是用于描述类有什么功能,但又不给出具体的实现。在Java中,接口可以看成是:多个类的公共规范,它对外提供一组规则,标准
2.2 接口的语法
Java提供了interface关键字,用来声明一个接口,接口的访问权限符只能是public或者默认
public interface 接口名{
//成员变量(常量)
//成员方法(抽象方法)
}
我们定义成员变量和成员方法时不需要在前面添加任何修饰符号。因为:
- 接口当中的成员变量,默认被public static final修饰,此时的成员变量也叫做常量,定义好后一定要记得初始化
- 接口当中的成员方法,默认被 public abstract修饰,此时的成员方法也就是抽象方法,不能有方法体
接口的定义格式和定义类的格式基本一样,把class关键字换成interface关键字,就定义好一个接口。我们可以让编译器帮我们创建接口,接口名要采用大驼峰的形式命名
2.3 接口的使用
接口不能直接使用,必须得有一个类来实现该接口,并且要实现接口中的所有抽象方法,此时这个类也就做:实现类
public class 类名 implements 接口名{
//……
}
要注意的是:在继承中,子类和父类之间是用extends来继承的;而类实现接口用的是implements实现的
2.4 接口的特性
- 接口类型是一种引用类型,但是我们不能直接new一个接口对象
- 接口中的方法都会被隐式指定为public abstract,接口中的变量都会被隐式指定为public static final
- 接口中不能有有静态代码块和构造器
- 重写接口中的方法时,要使用public修饰
- 如果类没有是实现接口中的所有抽象方法,那么该类必须设置为抽象类
- 在JDK8之后,接口中可以使用static和default修饰方法
2.5 接口的好处
在前面的学习中我们得知,类和类之间是单继承的,一个类只能有一个父类,不能支持多继承。但是一个类却可以是实现多个接口的(理论上是无数个)
一个类在实现多个接口时,每个接口中的抽象方法都要实现。否则该类必须设置为抽象类
既然如此,我们可以使用继承和接口,来让一个类的功能变得更加强大,更加全面
场景:要求设计一个People类里面包含人的一些基础信息(姓名、年龄、性别),还有一个Student类继承People类,再设计两个接口,功能包含跑步、唱歌等
People类:
public class People {
private String name;
private int age ;
private String gender;
public People(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
两个接口Running、Singing:
public interface Running {
void run();
}
public interface Singing {
void sing();
}
Student类:
public class Student extends People implements Running,Singing{
public Student(String name, int age, String gender) {
super(name, age, gender);
}
@Override
public void run() {
System.out.println(this.getName() + "在跑步~~~");
}
@Override
public void sing() {
System.out.println(this.getName() + "在唱歌~~~");
}
}
测试类Test:
public class Test {
public static void main(String[] args) {
Student student = new Student("张三",19,"男");
student.run();
student.sing();
}
}
运行结果如下:
从上面的例子我们可以看出,我们可以让一个类继承一个父类,代表它的是属于什么类型,接口则可以表示为该类具有什么功能,能做什么特有的事情,如果我们把功能全写进父类里,则不符合我们的常规逻辑:是人就一定会跑步吗、一定会唱歌吗。有了接口后,类的使用者就不用关心具体类型,只需要关注某个类是否具备某种能力就行
例子:我们实现一个“散步”方法
2.6 接口之间的继承
接口之间也能多继承,一个接口可以同时继承多个接口,相当于扩展了接口的能力,把多个接口合并到了一起
结语
关于抽象类和接口部分的知识就介绍到这里。在本篇博客中,咱介绍了抽象类和接口,以及它们的使用和特征。接口解决了类无法多继承的缺陷,同时接口之间也可以多继承,这一点十分的重要,接口的出现让面向对象的思想变得更加灵活开放,在下篇博客中我们会介绍接口的几个实际案例,带大家真正认识接口带给我们的好处。
希望大家能喜欢这篇文章,有总结不到位的地方还请多多谅解,若有出现纰漏,希望大佬们看到错误之后能够在私信或评论区指正,博主会及时改正,共同进步!