第二十五天接口、多态
1.java是面向对象的语言。
设计模式:接口
接口类是从java里衍生出来的,不是python原生支持的 主要用于继承里多继承
抽象类是python原生支持的主要用于继承里的单继承
但是接口类和抽象类都是为了写程序时进行代码的规范化
2.第一个接口类程序的引入:即如果前面写了两个支付功能,来了三个程序员写但是支付功能与前两个写的方法名称不一样怎么进行查询:
class Payment: def pay(self,money): raise NotImplemented #主动抛异常,表示没有执行此方法 class Wetchat(Payment): def pay(self,money): print('我们使用微信支付了%s钱'%money) class Alipay(Payment): def pay(self,money): print('我们使用阿里支付了%s钱'%money) class Apple (Payment): def fuqian(self,money): print('apple我们使用阿里支付了%s钱'%money) def pay(obj_payment,money): #定义此函数就不需要用户去指定哪一家去支付可以直接使用 obj_payment.pay(money) wechat=Wetchat() ali=Alipay() apple=Apple() pay(wechat,100) pay(ali,34) pay(apple,35)#如果没有这一个pa方法第一个写的会报错 结果为 pay(apple,35) File "D:/python练习程序/第二十五天/多态和继承.py", line 14, in pay obj_payment.pay(money) File "D:/python练习程序/第二十五天/多态和继承.py", line 3, in pay raise NotImplemented #主动抛异常,表示没有执行此方法 TypeError: exceptions must derive from BaseException
3上面这个程序是可以查询出在类的定义中某个方法有错误但是不知道具体是哪一个类写了错误,可以使用一下方法进行改进:
from abc import abstractmethod,ABCMeta class Payment(metaclass=ABCMeta): @abstractmethod #加了这个装饰器就可查看到是哪一个类和规范写的不一致 def pay(self,money):#元类默认的元类为type raise NotImplemented #主动抛异常,表示没有执行此方法 class Wetchat(Payment): def pay(self,money): print('我们使用微信支付了%s钱'%money) class Alipay(Payment): def pay(self,money): print('我们使用阿里支付了%s钱'%money) class Apple (Payment): def fuqian(self,money): print('apple我们使用阿里支付了%s钱'%money) def pay(obj_payment,money): #定义此函数就不需要用户去指定哪一家去支付可以直接使用 obj_payment.pay(money) wechat=Wetchat() ali=Alipay() apple=Apple() pay(wechat,100) pay(ali,34) pay(apple,35)#如果没有这一个pa方法第一个写的会报错 结果为 File "D:/python练习程序/第二十五天/多态和继承.py", line 19, in <module> apple=Apple() TypeError: Can't instantiate abstract class Apple with abstract methods pay
4进行程序的规范化接口类和抽象类都可以
使用接口类进行多继承的例子演示:
from abc import abstractmethod,ABCMeta class Swin_Animal(metaclass=ABCMeta): @abstractmethod def swim(self): pass class Walk_Animal: @abstractmethod def walk(self): pass class Fly_Animal: @abstractmethod def fly(self): pass class Tiger(Walk_Animal,Swin_Animal): def walk(self): pass class OldYing(Fly_Animal,Walk_Animal):pass class Swan(Swin_Animal,Walk_Animal,Fly_Animal):pass ret=Tiger() ret.swim()
5.接口隔离原则:
使用多个专门的接口,而不是单一的总接口。即客户端不应该依赖哪些不需要的接口。
6.抽象化的例子:记住系统中一切皆
import abc class All_file(metaclass=abc.ABCMeta): all_type='file' @abc.abstractmethod def read(self): '子类必须定义读功能' with open('filename')as f: pass @abc.abstractmethod def write(self): '子类功能必须有写的功能' pass class Txt(All_file): def read(self): print('文本数据的读取方法:') def write(self): print('进行文本数据的写入方法:') class Sata(All_file): def read(self): print('硬盘的数据读取方法') def write(self): print('硬盘的写入操作') class Process(All_file): def read(self): print('进程数据的读取方法') def write(self): print('进行数据的写入方法:') wenbenwenjian=Txt() yingpanwenjian=Sata() jinchengwenjian=Process() print(wenbenwenjian.all_type) print(yingpanwenjian.all_type) print(jinchengwenjian.all_type)
7。python天生支持多态:
8.那什么较多多态:就是指有些编程软件在进行数据传输的过程中需要进行类型的定义如果说在函数中定义的类型和传入的数据类型不一致,则会报错,需要写一个函数进行转换
但是python不需要。
9.paython里的数据类型属于动态强类型语言:鸭子类型。(两个类相似,并不会产生父类的子类之间的兄弟关系,就是鸭子类型)
10.看数据类型中的list和tuple
多态的特点:松耦合:每个相似的类之间都没有什么影响。
缺点:太随意靠自觉
11.封装:广义上面向对象的封装:代码的保护,面向对象的基本思想本省就是一种封装;只让自己的对象调用自己类中的方法
12.狭义的封装:属性和方法都被隐藏起来,不让自己看到
class Person: def __init__(self,name,passwd): self.name=name self.__passwd=passwd#对变量进行私有化 alex=Person('alex','alex1234') print(alex.passwd) 结果为 Traceback (most recent call last): File "D:/python练习程序/第二十五天/多态和继承.py", line 81, in <module> print(alex.passwd) AttributeError: 'Person' object has no attribute 'passwd'
13.那要怎么进行查看密码那:
class Person: def __init__(self,name,passwd): self.name=name self.__passwd=passwd#对变量进行私有化 alex=Person('alex','alex1234') print(alex.__dict__) #查看对象的所有属性 可以发现私有属性只能通过类来查看 结果为 {'name': 'alex', '_Person__passwd': 'alex1234'}
所以使用方法为:
class Person: def __init__(self,name,passwd): self.name=name self.__passwd=passwd#对变量进行私有化 alex=Person('alex','alex1234') print(alex.__dict__) #查看对象的所有属性 可以发现私有属性只能通过类来查看 print(alex._Person__passwd) #调用私有属性的方法 结果为 {'name': 'alex', '_Person__passwd': 'alex1234'} alex1234
方法二;
class Person: def __init__(self,name,passwd): self.name=name self.__passwd=passwd#对变量进行私有化 def get_passwd(self): return self.__passwd alex=Person('alex','alex1234') print(alex.__dict__) #查看对象的所有属性 可以发现私有属性只能通过类来查看 print(alex._Person__passwd) #调用私有属性的方法 print(alex.get_passwd()) #在类内部定义一个函数来取私有值: 结果为 {'name': 'alex', '_Person__passwd': 'alex1234'} alex1234 alex1234
14如果类被私有化之后应该怎们调用:
class Person: def __init__(self,name,passwd): self.name=name self.__passwd=passwd#对变量进行私有化 def get_passwd(self): return self.__passwd def __get(self): #只要在类的方法前面加上双下划线就是蒋类里的方法进行私有化 print('私有化被调用') alex=Person('alex','alex1234') print(alex.__dict__) #查看对象的所有属性 可以发现私有属性只能通过类来查看 print(alex._Person__passwd) #调用私有属性的方法 print(alex.get_passwd()) #在类内部定义一个函数来取私有值:
通过上述代码我们可以发现下图:(我们无法调用get方法)
15调用类中私有方法也是两种:
方法一
class Person: def __init__(self,name,passwd): self.name=name self.__passwd=passwd#对变量进行私有化 def get_passwd(self): return self.__passwd def __get(self): #只要在类的方法前面加上双下划线就是蒋类里的方法进行私有化 print('私有化被调用') alex=Person('alex','alex1234') print(alex.__dict__) #查看对象的所有属性 可以发现私有属性只能通过类来查看 print(alex._Person__passwd) #调用私有属性的方法 print(alex.get_passwd()) #在类内部定义一个函数来取私有值: alex._Person__get() 结果为 {'name': 'alex', '_Person__passwd': 'alex1234'} alex1234 alex1234 私有化被调用
方法二:
class Person: def __init__(self,name,passwd): self.name=name self.__passwd=passwd#对变量进行私有化 def get_passwd(self): return self.__passwd def __get(self): #只要在类的方法前面加上双下划线就是蒋类里的方法进行私有化 print('私有化被调用') def get_get(self): self.__get() alex=Person('alex','alex1234') print(alex.__dict__) #查看对象的所有属性 可以发现私有属性只能通过类来查看 print(alex._Person__passwd) #调用私有属性的方法 print(alex.get_passwd()) #在类内部定义一个函数来取私有值: alex._Person__get() #使用对象.类进行指向私有方法 alex.get_get() 结果为 C:\pycharm\python.exe D:/python练习程序/第二十五天/多态和继承.py {'name': 'alex', '_Person__passwd': 'alex1234'} alex1234 alex1234 私有化被调用 私有化被调用