面向对象的三大特性:继承、封装、多态
一、python面向对象的三大特性:继承、封装、多态
封装:把很多数据封装到一个对象中。把固定功能的代码封装到一个代码代码块、函数、对象、打包成模块。这都属于封装的思想。具体的情况具体分析,比如,你写了一个很NB的函数,那这个也可以被称之为封装。在面向对象思想中,是把一些看似无关紧要的内容组合到一起统一进行存储和使用,这就是封装。
继承:子类可以自动拥有父类中除了私有属性外的其他所有内容。先有父类再有子类。在python中实现继承非常简单,在声明类的时候,在类名后面添加一个小括号,就可以完成继承关系。
多态:同一个对象,多种形态。
二、封装
封装:将内容封装到某个地方,以后再去调用被封装在某处的内容
# 创建类
class Foo():
def __init__(self,name,age):
self.name = name
self.age = age
def detail(self):
print(self.name)
print(self.age)
# 根据类Foo创建对象
# 自动执行Foo类的__init__方法
obj1 = Foo("agen",15)
print(obj1.name) # 直接调用obj1对象的name属性
print(obj1.age) # 直接调用obj1对象的age属性
# 通过self间接调用被封装的内容
obj1.detail() # Python默认会将obj1传给self参数,所以此时方法内部的 self = obj1
# 根据类Foo创建对象
# 自动执行Foo类的__init__方法
obj2 = Foo("alex",15)
print(obj2.name) # 直接调用obj1对象的name属性
print(obj2.age) # 直接调用obj1对象的age属性
# 通过self间接调用被封装的内容
obj2.detail() # Python默认会将obj1传给self参数,所以此时方法内部的 self = obj1对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取封装的内容。
二、多态
多态:同一个对象,多种形态。python默认支持多态。(创建一个变量a=10,此时a是整数类型,通过程序让a="alex",a又变成了字符串类型,这就是多态性,同一个变量可以是多种形态)
鸭子类型:长得像鸭子,走路像鸭子,叫声也像鸭子,那么你就是鸭子。
三、类的约束
对类的约束有两种:
1、提取父类,然后在父类中定义好方法。在这个方法中什么都不用干,就抛一个异常就可以了,这样所有的子类都必须重写这个方法,否则,访问的时候出错。
2、使用元类来描述父类,在元类中给出一个抽象方方法,这样子类就不得不给出抽象方法的具体实现,也可以起到约束的效果。
第一种方法解决:
class Payment:
"""
此类什么都不做,就是制定一个标准,谁继承我,必须定义我里面的方法。
"""
def pay(self,money):
raise Exception("你没有实现pay方法")
class QQpay(Payment):
def pay(self,money):
print(‘使用qq支付%s元‘ % money)
class Alipay(Payment):
def pay(self,money):
print(‘使用阿里支付%s元‘ % money)
class Wechatpay(Payment):
def fuqian(self,money):
print(‘使用微信支付%s元‘ % money)
def pay(obj,money):
obj.pay(money)
a = Alipay()
b = QQpay()
c = Wechatpay()
pay(a,100)
pay(b,200)
pay(c,300)第二种方法:引入抽象类的概念处理。
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) # 到用的时候才会报错
# 抽象类和接口类做的事情 :建立规范
# 制定一个类的metaclass是ABCMeta,
# 那么这个类就变成了一个抽象类(接口类)
# 这个类的主要功能就是建立一个规范四、super()深入学习
super是严格按照类的继承顺序执行!!!
class A:
def f1(self):
print(‘in A f1‘)
def f2(self):
print(‘in A f2‘)
class Foo(A):
def f1(self):
super().f2()
print(‘in A Foo‘)
obj = Foo()
obj.f1()class A:
def f1(self):
print(‘in A‘)
class Foo(A):
def f1(self):
super().f1()
print(‘in Foo‘)
class Bar(A):
def f1(self):
print(‘in Bar‘)
class Info(Foo,Bar):
def f1(self):
super().f1()
print(‘in Info f1‘)
obj = Info()
obj.f1()
‘‘‘
in Bar
in Foo
in Info f1
‘‘‘
print(Info.mro()) # [<class ‘__main__.Info‘>, <class ‘__main__.Foo‘>, <class ‘__main__.Bar‘>, <class ‘__main__.A‘>, <class ‘object‘>]class A:
def f1(self):
print(‘in A‘)
class Foo(A):
def f1(self):
super().f1()
print(‘in Foo‘)
class Bar(A):
def f1(self):
print(‘in Bar‘)
class Info(Foo,Bar):
def f1(self):
super(Foo,self).f1()
print(‘in Info f1‘)
obj = Info()
obj.f1()