这篇文章我们来学习一下抽象与接口
目录
1.抽象
1.1 引出
1.2 抽象方法与抽象类
1.3 实际演示
2.接口
2.1接口的由来
2.2 接口的介绍
2.2.1接口的定义和使用
2.2.2 接口中成员的特点
2.2.3 接口和类之间的关系
2.2.4 实际演示
2.3 接口小结
3.小结
首先,我们来看一下抽象,抽象分为抽象类与抽象方法,二者其实都差不多,下面,我们来看一下。
抽象是面向对象的一部分,为了说明抽象的由来,我们先来回顾一下面向对象的三大特征。
首先是封装,就是将变量和方法给封装起来,当做类,当做一个模板。然后是继承,就是当有许多相同的类时,重复写很麻烦,我们抽取它们相同的变量和方法,将其封装起来,当做父类,然后其余的类继承它,写上自己独有的变量和方法,或者是重写父类的方法。多态呢,就是父类引用指向子类对象。
抽象是在继承的基础上提出的。在继承中我们会遇到这样一个问题,我们把一个方法抽取到父类中,如果写上具体的内容,那么有的子类可能就不适用了。为了解决这个,我们是在父类中的方法中随便写一点,然后子类继承时重写方法。但是这个方法有一个小小的弊端。就是当别人使用时,不一定知道要重写这个方法。那怎么办呢?继承后强制其重写方法,不写就报错。这就是抽象方法。有抽象方法的类叫抽象类
抽象方法:将共性的行为(方法)抽取到父类之后。由于每一个子类执行的内容是不一样的,所以,在父类中不能确定具体的方法体。该方法就可以定义为抽象方法。
抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类。
抽象方法定义格式:
public abstract void work();
注意:抽象方法不加 { },即不写方法体。
抽象类定义格式:
public abstract class Person {
}
注意:抽象类是在class前面加上 abstract
抽象类与抽象方法的注意事项:
下面实际演示一下抽象类与抽象方法的使用:
Person类:
package Day0402;
public abstract class Person {
private String name;
private int age;
//作用:当创建子类对象的时候,给属性进行赋值
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
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 abstract void work();
public void sleep(){
System.out.println("睡觉");
}
}
Student类:
package Day0402;
public class Student extends Person{
public Student() {
}
public Student(String name, int age) {
super(name, age);
}
@Override
public void work() {
System.out.println("学习");
}
}
测试类:
package Day0402;
public class Test {
public static void main(String[] args) {
Student student = new Student("张三",20);
System.out.println(student.getAge());
System.out.println(student.getName());
}
}
结果:
很简单,说白了,就是强制重写方法的继承。
下面,我们来介绍一下接口
首先,我们来介绍一下接口的由来。
要说接口的由来,就必须要再提一下前面讲的面向对象的三大特征。我们将变量与方法进行封装,封装成一个类,需要时直接new这个类的对象。而对同一类型的类,我们可以抽取里面相同的变量与方法,将其封装成父类,然后其余的类再继承它就行。但是有一个问题,就是所有在子类中,如果有90%有这个方法,10%没有这个方法,请问要不要把这个方法写到父类中?如果写的话,那就说明10%没有这个方法的类也会继承这个方法,这明显不合适。如果不写,那就要在剩下的90%的类中每一个都单独的写这个方法,属实比较麻烦。怎么办呢?用接口。接口就是一种规则,是对方法的抽象。
下面通过一个简单的案例,来讲一下接口在实际中的应用:
就比如我们定义一个搬家的方法,你传入搬家的工具,它给你实现搬家的功能。我们可以在参数列表中定义车,只要是车的子类都可以(因为多态),但是你不能传入搬家公司,因为它不是车的子类。
那怎么解决呢?我们来思考问题,我们要实现的是搬家的功能,不管你用什么方法,只要能搬家就行。所以现在搬家就是一种功能,是一种方法,是一种规则,我们可以定义一个接口,实现对方法的抽象,我不管你怎么搬,只要搬了,那就行。
接口与抽象类的不同点:
乍一看,接口与抽象类好像一样,但仔细想想,它们是不同的。抽象类是里面有抽象方法,当继承时,所以子类都会继承重写这个方法,意思就是,所有子类都有,但是具体到每一个子类中,却又不相同,那就是抽象类。而接口却是,有点类有,有的类没有,那就定义接口。接口实际上是对方法的抽象。
下面,我们来详细的介绍一下接口
接口的定义格式:public interface 接口名 { }
接口的使用:
public class 类名 implements 接口名 { }
注意事项:
接口和类之间是实现关系,可以单实现,也可以多实现,例如:
public class 类名 implements 接口名1,接口名2 { }
实现类还可以继承一个类的同时实现多个接口。例如:
public class 类名 extends 父类 implements 接口名1,接口名2 { }
成员无非就是成员变量,成员方法等内容
成员变量:接口中的变量只能是常量,且默认修饰符为:public static final
构造方法:没有
成员方法:只能是抽象方法;默认修饰符为 public abstract
JDK7以前:接口中只能定义抽象方法
JDK8的新特性:接口中可以定义有方法体的方法
JDK9的新特性:接口中可以定义私有方法
类和类之间的关系:继承关系,只能是单继承,不能是多继承,但是可以多层继承
类和接口的关系:实现关系,可以是单实现,也可以是多实现,还可以在继承一个类的同时实现多个接口
接口和接口的关系:继承关系,可以是单继承,也可以是多继承
下面来实际演示一下:
下面,来小结一下接口。
接口的语法规则简单,重点是要理解。接口说白了就是一种规则,是对方法的抽象,是方法的集合,接口实现了java没有的多继承功能。一般来说,接口里面全是抽象方法,我们把所有的方法都放到接口里面,然后让实现类来实现接口,并赋予实现类那些方法的功能,这样一想,是带点强制性的。并且,也可以用接口的引用指向实现类的对象。
这篇文章,我们学了抽象类和接口。从宏观层面说,抽象类是属于类的封装,接口是属于方法的封装,二者的共同属性是继承,而因为有了继承,就会出现多态现象。翻来覆去,就是那6个字:封装,继承,多态。封装是最最根本的思想,封装之后出现了继承,而多态就是为了解决继承的遗留问题而提出的。