面向对象(抽象类,接口类,多态,封装)
抽象类与接口类
接口类
继承有两种用途:
一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)
二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能
示例:
class Alipay: def __init__(self,money): self.money=money def pay(self): print("用支付宝支付了%s元" % self.money) class Taobaopay: def __init__(self,money): self.money=money def pay(self): print("用淘宝支付了%s" % self.money) a1=Alipay(250) a1.pay() t1=Taobaopay(500) t1.pay() 用支付宝支付了250元 用淘宝支付了500
实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。
继承的第二种含义非常重要。它又叫“接口继承”。
接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。
归一化设计示例:
class Alipay: def __init__(self,money): self.money=money def pay(self): print("用支付宝支付了%s元" % self.money) class Taobaopay: def __init__(self,money): self.money=money def pay(self): print("用淘宝支付了%s" % self.money) def pay(obj): obj.pay() a1=Alipay(250) t1=Taobaopay(500) pay(a1) pay(t1) 用支付宝支付了250元 用淘宝支付了500
制定规则,抽象类,接口类
from abc import ABCMeta,abstractclassmethod class Payment(metaclass=ABCMeta): # 抽象类(接口类): @abstractclassmethod def pay(self):pass # 制定了一个规范 class Alipay(Payment): def __init__(self,money): self.money=money def pay(self): print("用支付宝支付了%s元" % self.money) class Taobaopay(Payment): def __init__(self,money): self.money=money def pay(self): print("用淘宝支付了%s" % self.money) class Wechatpay(Payment): def __init__(self,money): self.money = money def pay(self): print('使用微信支付了%s' % self.money) def pay(obj): obj.pay() a1=Alipay(100) a1.pay() t1=Taobaopay(500) pay(t1) # 归一化设计 w1 = Wechatpay(300) w1.weixinpay() # 用的时候才会报错
python面向对象的三大特征之一:多态
多态: python处处是多态.
python 不管什么类型,传入函数,封装到对象中都可以.
python没有多态?他有什么? 他有鸭子类型.
鸭子类型 : 看着像鸭子,他就是鸭子.
这些类 都互称为鸭子.
class Str: def index(self): pass class List: def index(self): pass class Tuple: def index(self): pass
几个类中都有index方法
类的划分:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class A: company_name = '老男孩教育' # 静态变量(静态字段) __iphone = '1353333xxxx' # 私有静态变量(私有静态字段) def __init__(self,name,age): #普通方法(构造方法) self.name = name #对象属性(普通字段) self.__age = age # 私有对象属性(私有普通字段) def func1(self): # 普通方法 pass def __func(self): #私有方法 print(666) @classmethod # 类方法 def class_func(cls): """ 定义类方法,至少有一个cls参数 """ print('类方法') @staticmethod #静态方法 def static_func(): """ 定义静态方法 ,无默认参数""" print('静态方法') @property # 属性 def prop(self): pass
广义的封装: 实例化一个对象,给对象空间封装一些属性
狭义的封装: 私有制.
私有成员:私有静态字段,私有方法,私有对象属性
私有静态字段
class A: name = 'alex' def func(self): print('func....') a1 = A() print(a1.name) print(A.name) alex alex func....
实例化对象不能访问私有静态字段
class A: name = 'alex' __age=10 def func(self): print('func....') a1 = A() print(a1.__age) 结果:报错
类名不能访问私有静态字段
class A: name = 'alex' __age=10 def func(self): print('func....') a1 = A() print(A.__age) 结果:报错
所以:对于私有静态字段,类的外部不能访问.
class A: name = 'alex' __age=10 def func(self): print(self.__age) print('func....') a1 = A() a1.func() 10 func....
class A: name = 'alex' __age=10 def func(self): print(A.__age) print('func....') a1 = A() a1.func() 10 func....
由上可知:对于私有静态字段,类的内部可以访问.
对于私有静态字段来说,只能在本类中内部访问,类的外部,派生类均不可访问.
class B: __money=1000000 class A(B): name = 'alex' __age=10 def func(self): print(self.__age) print(A.__age) print('func....') def func1(self): print(self.__money) print(A.__age) a1 = A() a1.func1() 结果:报错
可以访问,但是工作中千万不要用.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class B: __money=1000000 class A(B): name = 'alex' __age=10 def func(self): print(self.__age) print(A.__age) print('func....') def func1(self): print(self.__money) print(A.__age) a1 = A() print(A._A__age) print(A.__dict__) 10 {'__module__': '__main__', 'name': 'alex', '_A__age': 10, 'func': <function A.func at 0x000001C50A5D8D90>, 'func1': <function A.func1 at 0x000001C50A5D8E18>, '__doc__': None}
私有方法
类外部不能访问
class B: __money = 100000 def __f1(self): print('B') class A(B): name = 'alex' def __func(self): print('func....') a1 = A() a1.__func() 结果:报错
类的内部可以访问
class B: __money = 100000 def __f1(self): print('B') class A(B): name = 'alex' def __func(self): print('func....') def func1(self): self.__func() a1 = A() a1.func1() func....
类的派生类也不能访问.
class B: __money = 100000 def __f1(self): print('B') class A(B): name = 'alex' def __func(self): print('func....') def func1(self): self.__f1() a1 = A() a1.func1() 结果:报错
练习题:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Parent: def __func(self): print('in Parent func') def __init__(self): self.__func() class Son(Parent): def __func(self): print('in Son func') son1 = Son()
私有对象属性
通过对象不可以访问
class A: def __init__(self): self.__name="name" a1 = A() a1.__name 结果:报错
通过类内部可以访问
class A: def __init__(self): self.__name="name" def func(self): print(self.__name) a1 = A() a1.func() 结果:name
通过派生类不可以访问
class A: def __init__(self): self.__name="name" def func(self): print(self.__name) class B(A): def func1(self): print(self.__name) a1 = B() a1.func1() 结果:报错