Java抽象类、抽象方法、接口
1、抽象类
1.1、为什么要有抽象类
我们学习继承的时候说过:父类是从子类中,抽象出共有属性和方法形成的。就说明父类相比于子类更加抽象。
而程序上有些类会十分的抽象,往往不需要再被实例化为对象。
这个时候我们就需要抽象类来禁止他被实例化。
因为我们往往是一个团队开发,有些类你知道不需要再被实例化,可别人不知道,口口相传又十分的影响效率。
我们就用抽象类来表明,该类不需要被实例化了。
1.2、什么是抽象类
抽象就是从多个事物中将共性的,本质的内容抽取出来。
而抽象类就是将本质的东西用语言描述出来。而因为过于抽象,已经没有了实例化的必要,所以变为抽象类
1.3、编写抽象类
abstract class [类名]{
}
就是使用上abstract关键字修饰这个类
这个类就不能被实例化了
abstract class Animal{
}
public class Test{
public static void main(String[] args){
Animal a = new Animal();//我们在编辑器中可以看到报错
}
}
抽象类的特点
- 无法被实例化
- 可以有抽象方法
1.4、抽象类的优势
提高可重用性
- 抽象类可以看作是类的一个模版,定义了子类的行为,可以为子类提供默认实现,无需子类中重复实现这些方法
代码松耦合,更易于维护
- 子类可以分别实现抽象父类中定义的抽象方法,将方法定义和方法实现的分离
方便实现多态
- 抽象类作为继承关系下的抽象层,不能被实例化,通常定义抽象类类型变量,其具体引用是实现抽象类的子类对象
2、抽象方法
2.1、为什么是抽象方法
打个比方,我们知道动物都是要吃饭的。
但我们都不清楚具体怎么吃。因为没有具体到某个动物
这个时候方法肯定是要抽象出来的,但是默认的吃法我们没有必要写出来,因为具体的动物是一定要描述自己怎么吃的。
这个时候我们就需要一个没有默认的方法体的方法,那就是抽象方法。
换言之,抽象方法其实就是没有默认实现的方法。也就是只有方法的名称,没有方法的实现
2.2、怎么写抽象方法
与抽象类相同,都是用abstract关键字修饰的方法
public abstract void test();
抽象方法的特点
- 抽象方法只有方法声明,没有方法实现
- 有抽象方法的类必须声明为抽象类
- 子类必须重写所有的抽象方法才能实例化;否则,子类也必须声明成抽象类
- 抽象类中可以没有、有一个或多个抽象方法,甚至可以定义全部方法都是抽象方法
- 抽象类可以有构造方法,其构造方法可以被本类的其他构造方法调用
- 不是由private修饰构造方法,可以被其子类的构造方法调用
3、接口
3.1、为什么需要接口
当我们抽象一个事物的时候,想要抽象父类,需要符合is-a原则。但是我们发现,共有一个父类的不同子类,也是拥有一些重复方法的。
举例:
假设我们有一个动物类作为抽象类
有三个子类分别是猫、老鹰、鹦鹉
可以发现,抽象类Animal提供了抽象方法eat()
子类对eat进行了重写
我们还能发现,老鹰和鹦鹉有相同的方法fly()
这相同的方法按继承来说,应该抽象出来
我们发现猫是不能飞的,也就不能被抽象到Animal中
我们有两个方案解决
- 解决方法一:
我们在创建Animal的子类Brid,让老鹰和鹦鹉继承bird,在bird里添加方法fly();
但是我们发现这个方法虽然能够解决,但还是有问题
比如我们要有个飞机类:
它也有飞的方法,但是我们有办法将它归类到动物类中吗?或者bird类?都不行
这样使用方法一就无法解决这个问题
所以就有了二
- 解决方法二:
使用接口解决。
我们创建一个接口,让他有一个飞的方法。
然后让有飞的能力的类,实现这个接口。
不仅解决了飞,还不用想继承关系
3.2、什么是接口
接入的端口,用现实来讲,一根水管的接口是圆的,我们就不会用方的,三角的去尝试接上,而是直接找一根圆形的接上就好了
在程序中也是,接口就是为了能够方便的让一些抽象方法能够被随意继承而存在。
某某类实现了某个接口,可以理解为某某类具有某种能力
总结一下:
生活中的接口就是一套规范
- 如:主板上的PCI插槽有统一的标准,规定了尺寸、排线
Java 中,接口
-
是一种规范和标准
- 可以约束类的行为,使得实现接口的类(或结构)在形式上保持一致
-
是一些方法特征的集合
- 可看作是一种特殊的“抽象类”
- 但采用与抽象类完全不同的语法
-
抽象类利于代码复用,接口利于代码的扩展和维护
3.3、接口怎么定义
interface [接口名]{
}
将创建普通类的class换成interface,就定义了一个接口
接口的几个注意点
-
接口中可以定义抽象方法
-
接口中的方法可以有方法体(两种)(1.8后才有):
- 加static关键字,转为静态方法
- 加default关键字,给方法一个默认实现
- 如果类实现的两个接口具有同名的默认实现方法,类需要重新实现这个方法
-
接口中定义的变量只能是静态全局常量
- 也就是static和final修饰的变量
-
接口中不能有构造方法
-
接口可以同时实现多个
-
一个接口可以继承多个接口,但接口不能继承类
3.4、如何实现接口
public class [类名] implements [接口名],[接口名2]{
}
通过在类名后使用implements关键字实现接口
4、面向对象设计的算则
为了让代码更具灵活性,更能适应变化,需遵循的原则
- 摘取代码中变化的部分,形成接口
- 多用组合,少用继承
- 面向接口编程,不依赖于具体实现
- 针对扩展开放,针对改变关闭
- ——开闭原则
经验:面向接口编程可以实现接口和实现的分离,能够在客户端未知的情况下修改实现代码