Iron music learning python_day21_ object-oriented programming 3

abstract classes and interface classes

Most of the following content is taken from the blog http://www.cnblogs.com/Eva-J/

Inheritance has two purposes:
one: inherit the methods of the base class, and make your own changes or extensions (code reuse);
two: declare that a subclass is compatible with a base class, define an interface class Interface, and the
interface class defines some The interface name (that is, the function name) does not implement the function of the interface. The
subclass inherits the interface class and implements the functions in the interface.

In practice, the first meaning of inheritance is not very meaningful, and is often even harmful. Because it makes the subclass strongly coupled to the base class.
The second meaning of inheritance is very important. It is also called "interface inheritance".
Interface inheritance essentially requires "to make a good abstraction that specifies a compatible interface,
so that external callers do not need to care about specific details, and can treat all objects that implement a specific interface equally" - this is in programming design. , called normalization.
Normalization allows high-level external users to indiscriminately handle all interface-compatible object sets - just like the Linux pan-file concept, everything can be handled as a file, regardless of whether it is memory, disk, network Still the screen.
(Of course, for the underlying designer, of course, it is possible to distinguish between "character device" and "block device",
and then make a targeted design: the degree of detail depends on the needs).

Digression: About java
Java is also an object-oriented programming language, but multiple inheritance is not allowed in java.
There are two good black books among java programmers:
design pattern programming, landmark design methods, which evolved from java
Example: singleton pattern ---- a class has only one instance
algorithm introduction calculation Methods, time, and space issues, authoritative and general.
Therefore, there are some programming principles and design patterns that can be used for reference in python programming.

python programming principles

Open closed principle
Open is open to extension
Closed is closed to modification

Dependency Inversion Principle
High-level modules should not depend on low-level modules, both should depend on their abstractions; abstractions should not depend on details; details should depend on abstractions. In other words, program for the interface, not for the implementation

The principle of interface isolation
(program code that has been written and delivered is generally not allowed to be modified.)
Use multiple specialized interfaces instead of a single general interface. That is, clients should not rely on those interfaces that are not needed.

支付功能的例子
    支付宝支付
    qq支付
    apply_pay
    微信支付

class Alipay:
    '''
    支付宝支付
    '''
    def pay(self,money):
        print('支付宝支付了%s元'%money)

class Applepay:
    '''
    apple pay支付
    '''
    def pay(self,money):
        print('apple pay支付了%s元'%money)

class Wechatpay:
    def fuqian(self,money):
        '''
        实现了pay的功能,但是名字不一样
        '''
        print('微信支付了%s元'%money)

def pay(payment,money):
    '''
    支付函数,总体负责支付
    对应支付的对象和要支付的金额
    '''
    payment.pay(money)

p = Wechatpay()
pay(p,200)   

#执行会报错
AttributeError: 'Wechatpay' object has no attribute 'pay'

使用ABC模块创建一个规范
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta):    # 抽象类 接口类  规范和约束  metaclass指定的是一个元类
    @abstractmethod
    def pay(self):pass  # 抽象方法

class Alipay(Payment):
    def pay(self,money):
        print('使用支付宝支付了%s元'%money)

class QQpay(Payment):
    def pay(self,money):
        print('使用qq支付了%s元'%money)

class Wechatpay(Payment):
    def pay(self,money):
        print('使用微信支付了%s元'%money)
    def recharge(self):pass

def pay(a,money):
    a.pay(money)    # 归一化设计:不管是哪一个类的对象,都调用同一个函数去完成相似的功能

a = Alipay()
a.pay(100)
pay(a,100)    
q = QQpay()
# q.pay(100)
pay(q,100)
w = Wechatpay()
pay(w,100)  

What abstract classes and interface classes do: establish specifications
If the metaclass of a class is ABCMeta,
then this class becomes an abstract class (interface class)
. The main function of this class is to establish a specification.

All methods decorated by abstractmethod in abstract classes must be implemented by inherited subclasses.
If they are not implemented, an error will be reported during the instantiation phase.

Neither abstract class nor interface class metaclass=ABCMeta can be instantiated
p = Payment() # Error

What is an abstract class

Like java, python also has the concept of abstract class, but it also needs to be implemented with the help of modules. An abstract class is a special class. Its special feature is that it can only be inherited and cannot be instantiated.

Why have abstract classes

If a class is said to extract the same content from a bunch of objects, then an abstract class is to extract the same content from a bunch of classes, including data attributes and function attributes.
  For example, we have a class of bananas, a class of apples, and a class of peaches. Extracting the same content from these classes is the abstract class of fruit. When you eat fruit, you either eat a specific banana or a specific one. peach. . . . . . You can never eat a thing called fruit.
From a design point of view, if the class is abstracted from the real object, then the abstract class is based on the class abstraction.
  From the perspective of implementation, the difference between abstract classes and ordinary classes is that abstract classes have abstract methods, which cannot be instantiated but can only be inherited, and subclasses must implement abstract methods. This is a bit similar to an interface, but it's actually different.

例:在python中实现抽象类 

# 模拟linux一切皆文件

import abc #利用abc模块实现抽象类

class All_file(metaclass=abc.ABCMeta):
    all_type='file'
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        '子类必须定义读功能'
        pass

    @abc.abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        '子类必须定义写功能'
        pass

# class Txt(All_file):
#     pass
#
# t1=Txt() #报错,子类没有定义抽象方法

class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('文本数据的读取方法')

    def write(self):
        print('文本数据的读取方法')

class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('硬盘数据的读取方法')

    def write(self):
        print('硬盘数据的读取方法')

class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('进程数据的读取方法')

    def write(self):
        print('进程数据的读取方法')

wenbenwenjian=Txt()

yingpanwenjian=Sata()

jinchengwenjian=Process()

#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()

print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)

What is an interface

There is no concept of interface in python, where does the concept of interface come from?
From java, java classes do not have multiple inheritance, interfaces can implement multiple inheritance.

例:描述动物园
会游泳的 会走路的 会爬树的 会飞的
老虎
青蛙
天鹅
猴子
from abc import ABCMeta,abstractmethod
class FlyAnimal(metaclass=ABCMeta):
    @abstractmethod
    def fly(self):pass
    @abstractmethod
    def cal_flying_speed(self):pass
    @abstractmethod
    def cal_flying_height(self):pass
class WalkAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):pass
class SwimAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):pass
class Tiger(WalkAnimal,SwimAnimal):
    def walk(self):pass
    def swim(self):pass
class Monkey:
    def walk(self):pass
    def climb(self):pass
class Swan(FlyAnimal,WalkAnimal,SwimAnimal):
    def swim(self):pass
    def walk(self):pass
    def fly(self):pass
    def cal_flying_speed(self):pass
    def cal_flying_height(self):pass
class Parrot(FlyAnimal):
    def fly(self):pass
    def cal_flying_speed(self):pass
    def cal_flying_height(self): pass

所有会飞的动物 具有一些会飞的动物的特性
所有会走的动物 具有一些会走的动物的特性

在python中根本就没有一个叫做interface的关键字,上面的代码只是看起来像接口,
其实并没有起到接口的作用,子类完全可以不用去实现接口 ,
如果非要去模仿接口的概念,可以借助第三方模块:
http://pypi.python.org/pypi/zope.interface
twisted的twisted\internet\interface.py里使用zope.interface
文档https://zopeinterface.readthedocs.io/en/latest/
设计模式:https://github.com/faif/python-patterns

The role of the interface class:

In java, the principle of interface isolation can be satisfied, and the constraints of multiple inheritance can be completed.
In python, the principle of interface isolation is satisfied. Since python itself supports multiple inheritance, the concept of interface is not needed.

abstract classes and interface classes

It's no different in python, both are used to constrain methods in subclasses.
As long as the methods decorated by abstractmethod in abstract classes and interface classes need to be implemented by subclasses.
It should be noted that when multiple classes have the same function and different functions, multiple interface classes should be used for separate constraints.
An abstract class is a specification for defining classes in python.
The essence of an abstract class is still a class, which refers to the similarity of a group of classes, including data attributes (such as all_type) and function attributes (such as read, write),
while the interface only emphasizes the similarity of function attributes.
Abstract class is a direct concept between class and interface. It has some characteristics of class and interface, and can be used to realize normalized design.

In python, there is no such thing as an interface class. Even if the interface is not defined through a special module, we should have some basic concepts.
In java, abstract classes and interfaces are very different.
The essence of an abstract class is still a class. If it is a class, it must follow the rules of single inheritance. Therefore, if a subclass is constrained by an abstract class,
it can only be controlled by a parent class. When multiple classes have the same function, there are also differences. When it comes to the function, java can only use the interface to solve the problem.
(using the interface keyword)

1. The problem of multiple inheritance
In the process of inheriting abstract classes, we should try to avoid multiple inheritance;
when inheriting interfaces, we instead encourage you to inherit multiple interfaces.

2. Implementation of methods
In abstract classes, we can make basic implementations of some abstract methods;
in interface classes, any method is just a specification, and specific functions need to be implemented by subclasses.

Note: When writing code in the company class, if you encounter an abstract class, remember to implement the corresponding methods one by one according to the specifications in the abstract class.

Why use an interface

An interface extracts a group of common functions, and an interface can be regarded as a collection of functions.
Then let the subclass implement the functions in the interface.
The significance of this is normalization. What is normalization is that as long as the classes are implemented based on the same interface, the objects generated by all these classes will be the same in terms of usage when used.
Normalization allows users not to care about the class of objects, but only to know that these objects have certain functions, which greatly reduces the difficulty for users to use.
For example: we define an animal interface, which defines interface functions such as running, eating, breathing, etc., so that the mouse class implements the interface, and the squirrel class also implements the interface, and the two generate a mouse respectively. And a squirrel brought to you, even if you can't tell which one is which, you know for sure that they can both run, eat, and breathe.
Another example: we have a car interface, which defines all the functions of the car, and then the Honda car class, the Audi car class, the Volkswagen class, they all implement the car interface, so it's easy to handle, everyone only needs If I learn how to drive a car, then whether it is Honda, Audi, or Volkswagen, we will drive it. When driving, we don't need to care what kind of car I drive, and the operation method (function call) is the same.

polymorphism

Polymorphism refers to the fact that a class of things has multiple shapes.
For example, animals have multiple shapes: humans, dogs, cats.

Files come in many forms: text files, executable files

import abc
class File(metaclass=abc.ABCMeta): #同一类事物:文件
    @abc.abstractmethod
    def click(self):
        pass

class Text(File): #文件的形态之一:文本文件
    def click(self):
        print('open file')

class ExeFile(File): #文件的形态之二:可执行文件
    def click(self):
        print('execute file')

polymorphism

1 What is polymorphic dynamic binding (sometimes called polymorphism when used in the context of inheritance)
Polymorphism is the use of an instance regardless of its type

In object-oriented methods, polymorphism is generally expressed as follows:
send the same message to different objects (!!!obj.func(): is the method func that calls obj, also known as sending a message func to obj) ,
different objects will have different behaviors (i.e. methods) when they are received.
That is, each object can respond to common messages in its own way.
The so-called message is to call a function, and different behaviors refer to different implementations, that is, to execute different functions.

For example: teacher. The bell rang after class (), student. The bell rang after class (), the teacher performed the off-duty operation, and the student performed the after-school operation.
Although the two messages are the same, the effect of the execution is different.

例:
peo=People()
dog=Dog()
pig=Pig()

#peo、dog、pig都是动物,只要是动物肯定有talk方法
#于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo.talk()
dog.talk()
pig.talk()

#更进一步,我们可以定义一个统一的接口来使用
def func(obj):
    obj.talk()

题外话:
java c++ c# —— 强类型语言
相同数据类型之间做运算
def func(int a):pass
func('a')

shell语言 —— 弱类型语言
1+'1'
def func(a):pass
1 'a' [1,2,3] ()

介于 强类型 与 弱类型之间 —— python 动态强类型语言
相同数据类型之间做运算
def func(a):pass

例:
class Payment:
    def pay(self):pass

class QQpay(Payment):
    def pay(self,money):
        print('使用qq支付了%s元'%money)

class Wechatpay(Payment):
    def pay(self,money):
        print('使用微信支付了%s元'%money)
    def recharge(self):pass

def pay(Payment pay_obj,int money):   
#  java 多态 在一个类之下发展出来的多个类的对象都可以作为参数传入这里
pay_obj.pay(money)

# 无论是python的2.*还是3.* : 天生自带多态效果
# qq_obj = QQpay()
# print(type(qq_obj))  # 一个对象的数据类型就是它所在的类

duck type

Funny Moment:
  Python embraces duck typing, i.e. 'if it looks like, quacks and walks like a duck, then it's a duck'
Python programmers usually write programs based on this behavior.
For example, if you want to write a custom version of an existing object, you can either inherit from that object, or you can create a completely new object that looks and behaves like it, but has nothing to do with it, which is often used to preserve the loose coupling of program components.

Example 1: Take advantage of the various 'file-like' objects defined in the standard library, although these objects work like files, they do not inherit the methods of the built-in file objects.

Example 2: There are many forms of sequence types: strings, lists, and tuples, but they have no direct inheritance relationship.

Example: We can say that QQpay and Wechatpay in the following example are duck types of each other.

class QQpay():
    def pay(self,money):
        print('使用qq支付了%s元'%money)

class Wechatpay():
    def pay(self,money):
        print('使用微信支付了%s元'%money)

def pay(pay_obj,money):
    pay_obj.pay(money)

Polymorphism and duck typing

Polymorphism implements
java through inheritance. Objects of multiple classes developed under a class can be passed into a function or method as a parameter;
in python, there is no need to deliberately implement polymorphism, because python itself has its own polymorphism effect.

Duck typing
does not constrain which method names must be in certain classes through a specific inheritance relationship;
it uses a conventional concept to ensure that similar functions in multiple classes have the same name.

end
2018-4-16

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324626846&siteId=291194637