接口跟抽象类的区别
抽象类
- 抽象类不允许被实例化,只能被继承。也就是说,你不能new一个抽象类的对象出来
- 抽象类可以包含属性和方法。方法既可以包含代码的实现,也可以不包含代码的实现。不包含代码实现的方法就叫做抽象方法
- 子类继承抽象类,必须实现抽象类中的所有抽象方法。
抽象类的举例:
import uuid
from abc import ABCMeta, abstractmethod
from time import time
class Wallet(metaclass=ABCMeta):
def __init__(self):
self._id = uuid.uuid4()
self._create_time = time()
self._balance = 0
self._balance_modified_time = time()
self.test = ''
@abstractmethod
def get_wallet_id(self): # 装饰器@abstractmethod定义了该方法为抽象方法
return self._id
@abstractmethod
def get_wallet_create_time(self): # 装饰器@abstractmethod定义了该方法为抽象方法
return self._create_time
def get_balance_modified_time(self):
return self._balance_modified_time
def increase_balance(self, increase_balance):
self._balance += increase_balance
def decrease_balance(self, decrease_balance):
self._balance -= decrease_balance
class UserWallet(Wallet):
"""子类必须实现基类的抽象方法,否则也会报错"""
def get_wallet_id(self): # 装饰器@abstractmethod定义了该方法为抽象方法
print('输出钱包id', 1)
return self._id
def get_wallet_create_time(self): # 装饰器@abstractmethod定义了该方法为抽象方法
return self._create_time
if __name__ == '__main__':
# w = Wallet() # 这里实例化会报错不能实例化拥有抽象方法的抽象类
# TypeError: Can't instantiate abstract class Wallet with abstract methods get_wallet_create_time, get_wallet_id
u = UserWallet()
u.get_wallet_id()
接口
- 接口不能包含属性(也就是成员变量)
- 接口只能声明方法,方法不能包含代码实现
- 类实现接口的时候,必须实现接口中声明的所有方法
python接口的例子:
下面的例子中,接口包含方法不包含实现,因此只要类中定义方法,将实现代码设置出抛异常,强制子类去实现就可以了
# python用普通类来模拟接口
class WalletA(object):
def get_wallet_id(self):
raise NotImplementedError("该方法必须实现")
def get_wallet_create_time(self):
raise NotImplementedError("该方法必须实现")
在面向对象编程中,什么时候使用抽象类跟接口?
- 实际上,当我们要表示一种is-a【某某类是】的关系,并且是为了解决代码复用的问题,就使用抽象类,如果要表示应has-a【某某类有】关系的话,并且是为了隐藏实现细节,只注重功能的时候,就可以使用接口。