抽象类
概念
抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类(abstract class)。
抽象方法
一种特殊的方法,它只有声明,没有具体的实现。抽象方法的访问限制必须是public或者protected,不能使用private修饰,因为抽象方法必须被子类继承且重写。此外,构造方法以及类方法不能被声明为抽象方法。在Java中,它使用关键字abstract声明。
public abstract void function();
在Python中,它使用装饰器的方式实现,由@abstractmethod 声明。
@abstractmethod
def function():
pass
抽象类的特征
- 不能使用抽象类创建具体的对象,即抽象类不能实例化,只有抽象类的非抽象子类可以创建对象;
- 抽象类可以包含抽象方法,也可以包含具体方法;
- 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为抽象类。
注:
- 包含抽象方法的类一定是抽象类,但抽象类不一定包含抽象方法。
- 包含抽象方法或者由abstract class关键字声明的类都是抽象类(Java语言中)。
实现
使用Java实现抽象类
在Java中,抽象类使用abstract class关键字来实现。例如,类Bird和类Duck继承自抽象类AbstractAnimal,必须要实现抽象类中的抽象方法,代码如下。
abstract class AbstractAnimal{
public abstract void calls();
}
class Bird extends AbstractAnimal{
public void calls(){
System.out.println("喳喳");
}
}
class Duck extends AbstractAnimal{
public void calls(){
System.out.println("嘎嘎");
}
}
public class AbstractClassExample {
public static void main(String[] args){
Duck duck = new Duck();
Bird bird = new Bird();
duck.calls();
bird.calls();
}
}
使用Python实现抽象类
在Python中,没有明确的抽象类,但是提供了一个模块abc来创建抽象基类。具体的,可以通过继承abc.ABC来创建,也可以通过将类的metaclass指定为ABCMeta来实现。
from abc import ABC,ABCMeta,abstractmethod
class AbstractAnimal(ABC):
# 声明calls()为抽象方法
@abstractmethod
def calls(self):
pass
class Bird(AbstractAnimal):
def calls(self):
print("喳喳")
class Duck(AbstractAnimal):
def calls(self):
print("嘎嘎")
bird = Bird()
duck = Duck()
bird.calls()
duck.calls()
接口
概念
接口
在面向对象编程中,接口是一种抽象类型,是抽象方法的集合,通过接口可以规定程序要做什么,但在接口中不具体实现。
接口的特征
- 接口不能被实例化,只有实现接口的非抽象类能创建实例对象。
- 接口中的每一个方法都会被隐式的指定为public abstract。
- 接口中的所有变量都会被隐式的指定为public static final。
- 接口中不含有构造方法。
- 接口中的抽象方法不能包含有具体实现,需要由实现其的非抽象类实现。
- JDK1.8之前,接口不能包含具体方法,JDK1.8之后,接口允许包含具体方法,用关键字default修饰;JDK1.8之前,接口不能包含静态方法,JDK1.8之后,接口允许包含静态方法。
实现
使用Java实现接口
在Java中,接口的创建和类相似,但由关键字interface来声明。接口更关注行为的约束,例如,类Bird和类Airplane都拥有“飞”这个行为,因此可以定义一个接口fly来抽象“飞”这个行为。
interface fly{
// 默认方法
default void defaultFun(){
System.out.println("接口中的默认方法!");
}
// 静态方法
static void staticFun(){
System.out.println("接口中的静态方法!");
}
// 抽象方法
abstract void flyfun();
}
class LittleBird implements fly{
public void flyfun(){
System.out.println("小鸟迎风飞翔!");
}
}
class AirPlane implements fly{
public void flyfun(){
System.out.println("飞机飞行!");
}
}
public class InterfaceExample {
public static void main(String[] args){
LittleBird littleBird = new LittleBird();
AirPlane airPlane = new AirPlane();
littleBird.flyfun();
airPlane.flyfun();
}
}
使用Python实现接口
在Python中,接口只是一个概念,没有明确的实现,一般使用class以及abc模块来实现接口。所以在Python中,接口更为灵活。
from abc import ABC,abstractmethod
class fly(ABC):
@staticmethod
def staticMethod():
print("接口中的静态方法!")
@abstractmethod
def flyfun(self):
pass
class LittleBird(fly):
def flyfun(self):
print("小鸟迎风飞翔!")
class AirPlane(fly):
def flyfun(self):
print("飞机在高空飞行!")
fly.staticMethod()
littleBird = LittleBird()
airPlane = AirPlane()
littleBird.flyfun()
airPlane.flyfun()
抽象类和接口的共同点和区别
共同点
- 都是一种抽象类型,都不可以被实例化;
- 都可以包含抽象方法;
- JDK1.8之后,接口和抽象类都允许包含具体的方法实现;
- JDK1.8之后,接口和抽象类都允许包含静态方法;
区别
- 抽象类是对类的抽象,而接口是对行为的抽象,即抽象类关注的是“is-a”,而接口关注的是“has-a”。
- 抽象类只支持单继承,接口支持多继承;
- 抽象类中的变量可以有多种类型的,而接口中的变量只能是public static final类型的;
- 抽象类中可以有静态代码块和构造方法,而接口中不可以有静态代码块和构造方法。
注: Python的类支持多继承,因此,Python中的抽象类和接口都支持多继承。