Python随记(13) 继承 组合 绑定

继承

将相似的东西得以自动传递。。。class 类名(被继承的类):
被继承的类叫基类,父类,超类,继承者称为子类。一个子类可以继承它的父类的所有属性和方法。
需要注意的是,如果子类中定义与父类同名的方法和属性,则会自动覆盖父类对应的方法和属性。

class Parent:
	def hello(self):
		print('hello')
class Child(Parent):
	pass
c=Child()
c.hello()
hello
class Child2(Parent):
	def hello(self):
		print('bey')
d=Child2()
d.hello()
bey

另外,子类重写了__init__()方法。父类定义的属性就是失效,要解决这个问题就要在子类中重写__init__()是先调用父类的方法。

方法一: 调用未绑定的父类方法

class Child(Parents):
	def __init__(self):
		Parents.__init__(self)

这个self并不是父类的实例对象,而是子类的,所以这里说的没绑定的是指并不需要绑定父类的实例对象,使用子类的额实例对象代替就行。(看不懂没关系,反正不重要。。)

方法二:super()函数 这个更好。。
super函数能自动找到父类的方法,而且还传入了self参数:

class Child(Parents):
	def __init__(self):
		super().__init__()	

super函数不需要明确给出任何父类的名字,他会自动赵卒所有父类以及其对应方法。由于不用给出父类的名字,这就意味着如果需要改变类继承关系,只要改变class语句中的父类就好,而不用去大量修改代码。

多重继承

就是同时继承多个父类的属性和方法,class 子类(父类1,父类2,父类3.。。) 但是多重继承容易导致代码混乱,所以要尽量避免他。

组合

class A:
	def __init__(self,x):
		self.num = x
class B:
	def __init__(self,x):
		self.num = x
class Big:
	def __init__(self,x,y):
		self.a=A(x)   #组合
		self.b=B(y)
	def getnum(self):
		print(self.a.num,self.b.num)
big = Big(1,2)
big.getnum()
1 2

就是把需要的类的实例放进去,,,

类、类对象、实例对象的关系
class C:
	count = 0
a=C() ; b=C() ; c=C()
print(a.count,b.count,c.count)  >>>0 0 0
c.count += 10
print(a.count,b.count,c.count)  >>>0 0 10
C.count += 100
print(a.count,b.count,c.count)  >>>100 100 10

对实例对象c的count属性进行赋值后,就相当于覆盖了类对象C的count属性,如果没有覆盖就引用类对象的count属性

类定义(C) =》 类对象(C) -》 类对象(a,b,c)

另外如果属性名与方法名相同,属性会覆盖方法,所以编码是要遵守一些约定俗成的规矩:

  1. 类的定义要‘少食多餐’ ,不要试图在一个类里面定义出所有所能想到的特征和方法,应该利用继承和组合机制来进行扩展
  2. 用不同的词性命名,属性用名词,方法用动词,使用驼峰命名法(CamelCase),指混合使用大小写字母来定义名字。

绑定

python严格要求方法需要有实例才能被调用,这种限制其实就是绑定。

class A:
	def setxy(self,x,y):
		self.x = x
		self.y = y
	def getxy(self):
		print(self.x,self.y)
>>> a=A()
>>> a.setxy(1,2)
>>> a.getxy()
1 2
>>> a.__dict__                  #__dict__方法可以查看对象的属性
{'x': 1, 'y': 2}
>>> A.__dict__
mappingproxy({'__module__': '__main__', 'setxy': <function A.setxy at 0x00000296D5DD80D0>, 'getxy': <function A.getxy at 0x00000296D5DD81F0>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})

可见x y这两个新属性只属于a这个实例化对象,就跟a绑定在了一起。。这就是self的作用,当a去调用setxy()方法,它传入的一个参数就是self(a ),也就是说self.x==a.x。
如果将类的实例删除,a还是能调用getxy()的。。del A a.getxy() >>1 2

在一个类中定义一个变量,追踪这个类有多少个实例对象

class C:
        count = 0
        
        def __init__(self):
                C.count += 1
 
        def __del__(self):
                C.count -= 1 
>>> a = C()
>>> b = C()
>>> c = C()
>>> C.count
3
>>> del a
>>> C.count
2
>>> del b, c
>>> C.count
0

_bases_
多继承的实现就会创建新类,有时,我们在运行时,希望给类A添加类B的功能时,也可以利用python的元编程特性,__bases__属性便在运行时轻松给类A添加类B的特性,如下代码:

A.__bases__ += (B,)
a.get_b()

其实__bases__也是继承的机制,因为__bases__属性存储了类的基类。因此多继承的方法也可以这样实现:

class C:
    pass 
C.__bases__ += (A, B, )
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值