Interface class
Inheritance has two purposes: inheriting the method of base class, making its own changes or extensions (code reuse) and declaring that a subclass is compatible with a base class, defining an interface class, defining some interface names (that is, function names) in the interface class and not realizing the function of the interface, subclass inherits the interface class and realizes the function of the interface.
For example, there are three different ways of payment: Alipay, Applepay, Wechatpay.
If there are only two ways of payment, Alipay and Wechatpay, how can we implement the payment method?
class Wechat: def pay(self,money): print('Payment has been made by Wechat.%s element'%money) class Alipay: def pay(self,money): print('Already paid for by Alipay.%s element'%money) wechat = Wechat() wechat.pay(200) #We have paid 200 yuan with Wechat. ali = Alipay() ali.pay(150) #Alipay has already paid 150 yuan.
But the downside is that users need to care about how they pay when they pay, and we just need to send a payee and money.
def pay(obj_pay,money): #Define a payment function obj_pay.pay(money) class Wechat: def pay(self,money): print('Payment has been made by Wechat.%s element'%money) class Alipay: def pay(self,money): print('Already paid for by Alipay.%s element'%money) wechat = Wechat() pay(wechat,300) #Wechat has been used to pay 300 yuan. ali = Alipay() pay(ali,250) #Alipay has already paid 250 yuan.
That's OK, but assuming a new Applepay-like payment method is added later, the difference between the method name and the payname will lead to an error.
from abc import abstractmethod,ABCMeta class Payment(metaclass=ABCMeta): @abstractmethod def pay(self,money): raise NotImplemented class Wechat(Payment): def pay(self,money): print('Payment has been made by Wechat.%s element'%money) class Alipay(Payment): def pay(self,money): print('Already paid for by Alipay.%s element'%money) class Apple(Payment): def payMoney(self,money): print('Already paid for by Alipay.%s element'%money) wechat = Wechat() ali = Alipay() apple = Apple() #Can't instantiate abstract class Apple with abstract methods pay
In this way, if the developer writes different method names and pays, the program will report errors in the instantiated object, which directly prompts the developer to write in a standardized way. If we change the method name in the Apple class back to the method name of pay, then we won't make a mistake.
class Apple(Payment): def pay(self,money): print('Already paid for by Alipay.%s element'%money) apple = Apple()
Multiple Inheritance of Interfaces
If we sum up the behavior of the following three animals, tigers can walk and swim; swans can fly, walk and swim; Eagles can walk and fly, how can we express it by means of interface?
from abc import abstractmethod,ABCMeta class Swim_Behavior(metaclass=ABCMeta): @abstractmethod def swim(self): pass class Walk_Behavior(metaclass=ABCMeta): @abstractmethod def walk(self): pass class Fly_Behavior(metaclass=ABCMeta): @abstractmethod def fly(self): pass class Tiger(Swim_Behavior,Walk_Behavior): def walk(self): print('Can walk!') def swim(self): print('Can swim!') class Swan(Swim_Behavior,Walk_Behavior,Fly_Behavior): def walk(self): print('Can walk!') def swim(self): print('Can swim!') def fly(self): print('Can fly!') class Hawk(Walk_Behavior,Fly_Behavior): def walk(self): print('Can walk!') def fly(self): print('Can fly!') t = Tiger() s = Swan() h = Hawk()
The method of the interface class itself is not implemented, it just plays a normative role.
Interface isolation principle:
Use multiple specialized interfaces instead of a single master interface. That is, clients should not rely on unnecessary interfaces
Special interface refers to the above animal walk using the walk interface, fly using the fly interface, swim using the swim interface.
Not using a single interface means that you shouldn't use an interface that has the behavior of both walk and fly. Only by separating each function, we can inherit all its relevant variable names and method names when we use this function later.
That is, the client shouldn't rely on unnecessary interfaces means that creating a Tiger class should not rely on classes that it does not own, such as fly.
abstract class
Abstract class is a special class, its special point is that it can only be inherited, can not be instantiated.
If a class comes from extracting the same content from a bunch of objects, then an abstract class comes from extracting the same content from a bunch of classes, including data attributes and function attributes.
#Everything is a file in the operating system from abc import abstractmethod,ABCMeta class All_file(metaclass=ABCMeta): all_type = 'file' #All types are files @abstractmethod #Defining an abstract method requires no functionality def write(self): pass @abstractmethod #Defining an abstract method requires no functionality def read(self): pass class Txt(All_file): #Define a Txt class,Subclasses inherit abstract classes,But one must be defined write and read Method def write(self): print('Write something...') def read(self): print('Read something...') class Sata(All_file): #Define a Sata class,Subclasses inherit abstract classes,But one must be defined write and read Method def write(self): print('Write something...') def read(self): print('Read something...') txt = Txt() sata = Sata() txt.read() #Read something... txt.write() #Write something... sata.read() #Read something... sata.write() #Write something... print(txt.all_type) #file print(sata.all_type) #file
Abstract class is a specification, in general, single inheritance can achieve the same function, so there are some simple basic implementations in the parent class; multi-inheritance can not easily abstract the same function because of its complex function, and the specific implementation is written in the parent class.
Summary of interface classes and abstract classes
There is no interface class in python, but there are abstract classes; metaclass = ABCMeta,@abstractmethod in abc module is essentially used for code specification, hoping that the parent class name can be exactly the same in subclasses.
Interface classes and abstract classes:
From the point of view of java, there are differences. Java already supports single inheritance, so there are abstract classes; Java does not have multiple inheritance, so for the principle of interface isolation, the concept of interface is designed to support multiple inheritance.
Python supports both single inheritance and multi-inheritance, so the distinction between interface classes and abstract classes is not so obvious, even there is no built-in interface class in python.
polymorphic
Polymorphism refers to the fact that a class of things has many forms.
python naturally supports polymorphism
from abc import abstractmethod,ABCMeta class Payment(metaclass=ABCMeta): #Payment Method Category @abstractmethod def pay(self,money): pass class Wechat(Payment): #Payment method---Wechat Payment def pay(self,money): print('Payment has been made by Wechat.%s element'%money) class Alipay(Payment): #Payment method---Alipay payment def pay(self,money): print('Already paid for by Alipay.%s element'%money) class Apple(Payment): #Payment method---Apple Payment def pay(self,money): print('Already paid for by Alipay.%s element'%money)
Polymorphism
Although it is a kind of thing, they execute the same method but do different things. For example, WeChat uses WeChat payment, Alipay uses Alipay payment, apple pays it for Apple payment.
Duck type
In python there is a concept of duck type, while in some other strongly typed languages, polymorphism is used.
Duck type: I don't advocate the similarity based on inheritance. I just implement my own code. If there are two classes which are just similar and do not produce sibling relationship between the parent and the child, then this is the duck type. Similar to list and tuple, they are constrained when they write their own code, not through parent constraints.