一、抽象类
1.1. 概念及特点:
如果一个类中
没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类,它表示的是一种继承关系。抽象类
除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。抽象类
必须被继承,才能被使用。父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
通过关键字
abstract定义。
1.2. 抽象类的使用:
-
首先我们定义几个抽象类,继承关系如下:
-
动物抽象类
abstract class Animal {
public abstract void drink();
}
- 鸟类抽象类
abstract class Birds extends Animal {
public abstract void fly();
}
- 鱼类抽象类
abstract class Fishes extends Animal{
public abstract void swim();
}
- 老鹰实体类
/* *
* 老鹰是一个实体类,所以它必须重写所有继承自超类的抽象方法。
* 至于具体的重写实现方式,取决于老鹰类本身。
* 后面的蜂鸟实体类以及鲨鱼实体类同上。
*/
public class Eagle extends Birds{
@Override
public void drink() {
}
@Override
public void fly() {
System.out.println("善于在高空持久盘旋翱翔");
}
}
- 蜂鸟实体类
public class Hummingbird extends Birds{
@Override
public void drink() {
}
@Override
public void fly() {
System.out.println("两翅急速拍动,快速有力而持久");
}
}
- 鲨鱼实体类
public class Shark extends Fishes{
@Override
public void drink() {
}
@Override
public void swim() {
System.out.println("摆动式地向前推进");
}
}
1.3.问题:当我们需要增加一个特殊的肉食方法时候,应该怎样去设计?
方式一: 在Animal类添加食肉方法。(若这样实现,则所有它的非抽象派生类都需要重写这个方法,这么做显然是不合理的。)
方法二: 在需要使用到该方法的实体类进行添加。(若这样实现,则会冗余且不具有通用性。)
方法三: 在Birds、Fishes类下新增加Carnivores[ 肉食动物抽象类]。(若这样实现,则会使得类族图越来越复杂,代码变得更加难以维护。)
上面的问题, 抽象类解决不了, 根本问题是Java的
类不能多继承。这个时候,
接口就发挥作用了。
二、接口概述
2.1. 什么是接口?
接口(interface):接口用来描述类应该做什么,而不是指定它们具体应该如何做。
从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
2.2. 为什么要使用接口?
因为Java不像C++一样支持多继承,接口与实现类之间存在
多态性,所以Java可以通过实现接口来弥补这个局限。接口也被用来实现
解耦。
2.3. 接口有哪些特点?
接口中的所有方法都自动是
public方法 ,且在接口声明方法时,不必提供关键字public。在
实现接口时,必须把方法声明为public。不能通过
new关键字实例化接口。定义一个接口使用
interface关键字。若要将类声明为实现某个接口,则需要使用implements关键字。一个类可以实现一个或多个接口。
Java8中,允许接口中增加
静态方法。Java9中,接口方法可以是
private修饰。(只是用法有限,只能作为接口中其他方法的辅助方法。)
三、 接口使用
3.1. 接口定义
/* *
* 通过interface关键字定义一个FoodHabit接口
*/
public interface FoodHabit {
void eatMeat();
}
3.2. 接口实现
/* *
* 老鹰是一个实体类,它继承Birds类,实现FoodHabit接口。
*
*/
public class Eagle extends Birds implements FoodHabit{
@Override
public void drink() {
}
@Override
public void fly() {
System.out.println("善于在高空持久盘旋翱翔");
}
@Override
public void eatMeat() {
System.out.println("老鹰是肉食动物");
}
}
public class Shark extends Fishes implements FoodHabit {
@Override
public void drink() {
}
@Override
public void swim() {
System.out.println("摆动式地向前推进");
}
@Override
public void eatMeat() {
System.out.println("鲨鱼是食肉动物");
}
}
3.3. 总结:什么情况下应该使用接口而不用抽象类?
需要实现多态。
要实现的方法(功能)不是当前类族的必要(属性)。
要为不同类族的多个类实现同样的方法(功能)。
四、生活中的“接口思想”
五、结束语
“-------怕什么真理无穷,进一寸有一寸的欢喜。”
微信公众号搜索:饺子泡牛奶。