<h2 >一、继承
1,什么是继承继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类python中类的继承分为:单继承和多继承ParentClass1:
<span >class
ParentClass2: <span >#<span >定义父类<span >pass
<span >class SubClass1(ParentClass1): <span >#<span >单继承,基类是ParentClass1,派生类是SubClass
<span >pass
<span >class SubClass2(ParentClass1,ParentClass2): <span >#<span >python支持多继承,用逗号分隔开多个继承的类,SubClass2就是多继承
2,查看继承
>>> SubClass1. (< >>>> SubClass2.< >,< >)提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。
>>> ParentClass1.< >>>> ParentClass2.< >,)3,继承与抽象(先抽象再继承)
抽象即抽取类似或者说比较像的部分。
抽象分成两个层次:
1.将奥巴马和梅西这俩对象比较像的部分抽取成类;
2.将人,猪,狗这三个类比较像的部分抽取成父类。
继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。
4,继承与重用性
========================== 猫可以:喵喵叫、吃、喝、拉、撒狗可以:汪汪叫、吃、喝、拉、撒
如果我们要分别为猫和狗创建一个类,那么就需要为 猫 和 狗 实现他们所有的功能,伪代码如下:
<span >#<span >猫和狗有大量相同的内容<span >class<span > 猫:
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 喵喵叫(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">喵喵叫</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 吃(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 喝(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 拉(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 撒(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span>
<span >class
<span > 狗:</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 汪汪叫(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">汪汪叫</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 吃(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 喝(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 拉(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 撒(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span>
==========================<span >第二部分
上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。如果使用 继承 的思想,如下实现:
动物:吃、喝、拉、撒
猫:喵喵叫(猫继承动物的功能)
狗:汪汪叫(狗继承动物的功能)
伪代码如下:
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 吃(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 喝(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 拉(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 撒(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> do something</span>
<span >#
<span > 在类后面括号中写入另外一个类名,表示当前类继承另外一个类<span >class<span > 猫(动物):
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 喵喵叫(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">喵喵叫</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span>
<span >#
<span > 在类后面括号中写入另外一个类名,表示当前类继承另外一个类<span >class<span > 狗(动物):
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> 汪汪叫(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">汪汪叫</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span>
==========================<span >第三部分
<span >class<span > Animal:
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> eat(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000"><a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> 吃 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span> %<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> drink(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span> (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000"><a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> 喝 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span> %<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> shit(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span> (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000"><a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> 拉 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span> %<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> pee(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span> (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000"><a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> 撒 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span> %<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)
<span >class<span > Cat(Animal):</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080"><a href="https://www.jb51.cc/tag/init/" target="_blank" >__init__</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">(self,<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>): self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a> </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> <a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a> self.breed </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">猫</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> cry(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">喵喵叫</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)
<span >class<span > Dog(Animal):</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080"><a href="https://www.jb51.cc/tag/init/" target="_blank" >__init__</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">(self,<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>): self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a> </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> <a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a> self.breed</span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">狗</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> cry(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">汪汪叫</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)
<span >#<span > ######### 执行 #########<span >
c1 = Cat(<span >'<span >小白家的小黑猫<span >'<span >)
c1.eat()
c2
= Cat(<span >'<span >小黑的小白猫<span >'<span >)c2.drink()
d1 = Dog(<span >'<span >胖子家的小瘦狗<span >'<span >)
d1.eat()
使用继承来重用代码比较好的例子
使用继承来解决代码重用的例子
在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时
我们不可能从头开始写一个类B,这就用到了类的继承的概念。
通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用
= name self.aggressivity = aggressivity self.life_value = life_value<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> eat(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000"><a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> is eating</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span>%<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)
<span >class<span > Dog(Animal):<span >pass
<span >class
<span > Person(Animal):<span >pass<span >
egg
= Person(<span >'<span >egon<span >',10,1000<span >)ha2 = Dog(<span >'<span >二愣子<span >',50,1000<span >)
egg.eat()
ha2.eat()
5,派生
当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。
= name self.aggressivity = aggressivity self.life_value = life_value<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> eat(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000"><a href="https://www.jb51.cc/tag/s/" target="_blank" >%s</a> is eating</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span>%<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">self.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>)
<span >class<span > Dog(Animal):<span >'''<span >
狗类,继承Animal类
<span >'''
<span >def<span > bite(self,people):
<span >'''<span >
派生:狗有咬人的技能
:param people:
<span >'''<span >
people.life_value -=<span > self.aggressivity<span >class<span > Person(Animal):
<span >'''<span >
人类,继承Animal
<span >'''
<span >def<span > attack(self,dog):
<span >'''<span >
派生:人有攻击的技能
:param dog:
<span >'''<span >
dog.life_value -=<span > self.aggressivity
egg = Person(<span >'<span >egon<span >',1000<span >)
<span >print<span >(ha2.life_value)
<span >print<span >(egg.attack(ha2))
<span >print(ha2.life_value)
在子类中,新建的重名的函数属性,在编辑函数内功能的时候,有可能需要重用父类中重名的那个函数功能,应该是用调用普通函数的方式,即:类名.func(),此时就与调用普通函数无异了,因此即便是self参数也要为其传值.
6,super
(<span >class<span > B(A):<span >def<span > hahaha(self):
super().hahaha()
<span >#<span >super(B,self).hahaha()
<span >#<span >A.hahaha(self)
<span >print(<span >'<span >B<span >'<span >)
a =<span > A()
b =<span > B()
b.hahaha()
super(B,b).hahaha()
<span >def<span > hahaha(self):
super().hahaha()
<span >#<span >super(B,b).hahaha()
帮你了解super
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。
当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师
>>> ==(>>> >>> >>> p1=Professor(,>>>7,钻石继承
继承顺序当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找
经典类和新式类:
从写法上类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
(<span >class<span > B(A):<span >def<span > test(self):
<span >print(<span >'<span >from B<span >'<span >)<span >class<span > C(A):
<span >def<span > test(self):
<span >print(<span >'<span >from C<span >'<span >)<span >class<span > D(B):
<span >def<span > test(self):
<span >print(<span >'<span >from D<span >'<span >)<span >class<span > E(C):
<span >def<span > test(self):
<span >print(<span >'<span >from E<span >'<span >)<span >class<span > F(D,E):
<span >#<span > def test(self):
<span >#<span > print('from F')
<span >pass<span >
f1=<span >F()
f1.test()
<span >print(F.<span >mro) <span >#<span >只有新式才有这个属性可以查看线性列表,经典类没有这个属性
<span >#<span >新式类继承顺序:F->D->B->E->C->A<span >
<span >经典类继承顺序:F->D->B->A->E->C<span ><span >python3中统一都是新式类<span ><span >pyhon2中才分新式类与经典类8,继承原理
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列
>>> F.mro() [< >,< >,< >,< >,< >,< >,< >]为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:1.子类会先于父类被检查2.多个父类会根据它们在列表中的顺序被检查3.如果对下一个类存在两个合法的选择,选择第一个父类
二、多态1,抽象类与接口类继承有两种用途:
一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)
二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能
(%<span >class<span > Applepay:<span >'''<span >
apple pay支付
<span >'''
<span >def<span > pay(self,money):
<span >print(<span >'<span >apple pay支付了%s元<span >'%<span >money)<span >def<span > pay(payment,money):
<span >'''<span >
支付函数,总体负责支付
对应支付的对象和要支付的金额
<span >'''<span >
payment.pay(money)
p
=<span > Alipay()pay(p,200) (%<span >class<span > Wechatpay:
<span >def<span > fuqian(self,money):
<span >'''<span >
实现了pay的功能,但是名字不一样
<span >'''
<span >print(<span >'<span >微信支付了%s元<span >'%<span >money)<span >def<span > pay(payment,money):
<span >'''<span >
支付函数,总体负责支付
对应支付的对象和要支付的金额
<span >'''<span >
payment.pay(money)
p
=<span > Wechatpay()pay(p,200) <span >#<span >执行会报错
借用abc模块来实现接口
abc <span >class Payment(Metaclass=<span >ABCMeta):@abstractmethod
<span >def<span > pay(self,money):
<span >pass
<span >class
<span > Wechatpay(Payment):<span >def<span > fuqian(self,money):
<span >print(<span >'<span >微信支付了%s元<span >'%<span >money)
p
= Wechatpay() <span >#<span >不调就报错了实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。
继承的第二种含义非常重要。它又叫“接口继承”。接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。
归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合——就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)。
抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化
abc<span >class
All_file(Metaclass=<span >abc.ABCMeta):all_type=<span >'<span >file<span >'<span >
@abc.abstractmethod <span >#<span >定义抽象方法,无需实现功能
<span >def<span > read(self):
<span >'<span >子类必须定义读功能<span >'
<span >pass<span >
@abc.abstractmethod </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">定义抽象<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a>,无需实现<a href="https://www.jb51.cc/tag/gongneng/" target="_blank" >功能</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> write(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">子类必须定义写<a href="https://www.jb51.cc/tag/gongneng/" target="_blank" >功能</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">pass</span>
<span >#<span > class Txt(All_file):<span >
<span > pass<span ><span > t1=Txt() #报错,子类没有定义抽象方法<span >class Txt(All_file): <span >#<span >子类继承抽象类,但是必须定义read和write方法
<span >def<span > read(self):
<span >print(<span >'<span >文本数据的读取方法<span >'<span >)
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> write(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">文本数据的读取<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)
<span >class Sata(All_file): <span >#<span >子类继承抽象类,但是必须定义read和write方法
<span >def<span > read(self):
<span >print(<span >'<span >硬盘数据的读取方法<span >'<span >)
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> write(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">硬盘数据的读取<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)
<span >class Process(All_file): <span >#<span >子类继承抽象类,但是必须定义read和write方法
<span >def<span > read(self):
<span >print(<span >'<span >进程数据的读取方法<span >'<span >)
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> write(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">进程数据的读取<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)
wenbenwenjian=<span >Txt()
yingpanwenjian=<span >Sata()
jinchengwenjian=<span >Process()
<span >#<span >这样大家都是被归一化了,也就是一切皆文件的思想
<span >wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()
<span >print<span >(wenbenwenjian.all_type)
<span >print<span >(yingpanwenjian.all_type)
<span >print(jinchengwenjian.all_type)
<div >
12<span >.方法的实现
在抽象类中,我们可以对一些抽象方法做出基础实现;
而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现
python中没有接口类,有抽象类,abc模块中的Metaclass =ABCMeta,@abstrutmethod
本质是做代码规范用的,希望在子类中实现和父类方法名字完全一样的方法
在Java的角度来看是有区别的:
Java本来就支持单继承,所以就有了抽象类
Java没有多继承,所以为了接口隔离原则,设计了接口这个概念
python即支持单继承页支持多继承,所以对于接口类和抽象类的区别就不明显了。
甚至在python中没有内置接口类。
2,多态
多态指的是一类事物有多种形态
动物有多种形态:人,狗,猪
Animal(Metaclass=abc.ABCMeta):<span >class
People(Animal): <span >#<span >动物的形态之一:人<span >def<span > talk(self):
<span >print(<span >'<span >say hello<span >'<span >)
<span >class Dog(Animal): <span >#<span >动物的形态之二:狗
<span >def<span > talk(self):
<span >print(<span >'<span >say wangwang<span >'<span >)
<span >class Pig(Animal): <span >#<span >动物的形态之三:猪
<span >def<span > talk(self):
<span >print(<span >'<span >say aoao<span >')
<span >peo.talk()
dog.talk()
pig.talk()
<span >#<span >更进一步,我们可以定义一个统一的接口来使用
<span >def<span > func(obj):
obj.talk()
4,鸭子类型---不依赖父类的情况下实现两个相似的类中的同名方法
<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> write(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">pass</span>
<span >class
<span > diskfile:<span >def<span > read(self):
<span >pass
<span >def<span > write(self):
<span >pass三、封装--私有的
在python中只要___名字,就把这个名字私有化了
私有化之后,就不能从类的外部直接调用了
静态属性、方法对象属性、都可以私有化
这种私有化只是从代码级别做了变性并没有真的约束
变形机制:_类名__名字,在类外用这个调用,在累得内部直接__名字调用
在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)
<span >class
<span > A:<span >N=0 <span >#<span >类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_AN
<span >def <span >init<span >(self):
self.<span >X=10 <span >#<span >变形为self._AX
<span >def <span >foo(self): <span >#<span >变形为_Afoo
<span >print(<span >'<span >from A<span >'<span >)
<span >def<span > bar(self):
self.<span >foo() <span >#<span >只有在类内部才可以通过foo的形式访问到.
<span >#<span >A._A__N是可以访问到的,即这种 *** 作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形
这种自动变形的特点:
1.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。
2.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
3.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。
这种变形需要注意的问题是:
1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N
2.变形的过程只在类的内部生效,在定义后的赋值 *** 作,不会变形
3.在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的
= = = self. type(newname) str newname.isdigit() == =( self. * self.jin = Room(<span >'<span >金老板<span >',2,1<span >)<span >print<span >(jin.area())
jin.set_name(<span >'<span >2<span >'<span >)
<span >print(jin.get_name())
并不能修改私有化属性
>>> (>>> (>>> b=>>><span >#<span >把fa定义成私有的,即__fa<span > A:<span >class
... <span >def <span >fa(self): <span >#<span >在定义时就变形为_Afa
... <span >print(<span >'<span >from A<span >'<span >)
... <span >def<span > test(self):
... self.<span >fa() <span >#<span >只会与自己所在的类为准,即调用_A__fa
<span >...
>>> <span >class<span > B(A):
... <span >def <span >fa<span >(self):
... <span >print(<span >'<span >from B<span >'<span >)
...
>>> b=<span >B()
>>><span > b.test()
<span >from A
会用到私有的这个概念de场景1.隐藏起一个属性 不想让类的外部调用2.我想保护这个属性,不想让属性随意被改变3.我想保护这个属性,不被子类继承2,property属性什么是特性propertyproperty是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖,高于32
体质指数(BMI)=体重(kg)÷身高^2(m)
EX:70kg÷(1.75×1.75)=22.86
<div >
<img ID="code_img_closedaa5a0c36-9180-4c4a-abe7-e2e317620b44" src="https://www.jb51.cc/res/2019/02-25/18/1c53668bcee393edac0d7b3b3daff1ae.gif" alt=""><img ID="code_img_openedaa5a0c36-9180-4c4a-abe7-e2e317620b44" src="https://www.jb51.cc/res/2019/02-25/18/405b18b4b6584ae338e0f6ecaf736533.gif" alt=""><div ID="cnblogs_code_open_aa5a0c36-9180-4c4a-abe7-e2e317620b44" >
== self.weight/(self.length)**2=Bmi(62,1.8(a.bmi)
(self,radius): self.radius=@property</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> area(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">return</span> math.pi * self.radius**2 <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">计算面积</span>
<span >
@property
<span >return 2math.piself.radius <span >#<span >计算周长
<span >
c=Circle(10<span >)
<span >print<span >(c.radius)
<span >print(c.area) <span >#<span >可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
<span >print(c.perimeter) <span >#<span >同上
<span >'''<span >
输出结果:
314.1592653589793
62.83185307179586
<span >'''<span >
例二:圆的周长和面积
为什么要用property
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
python并没有在语法上把它们三个内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现
=val self. isinstance(value,str): TypeError( %=value TypeError(f=Foo(<span >'<span >egon<span >'<span >)<span >print<span >(f.name)
<span >#<span > f.name=10 #抛出异常'TypeError: 10 must be str'
<span >del f.name <span >#<span >抛出异常'TypeError: Can not delete'
一个静态属性property本质就是实现了get,set,delete三种方法
(@AAA.setter</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> AAA(self,value): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">set的时候运行我啊</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)@AAA.deleter</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> AAA(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">delete的时候运行我啊</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)
<span >#<span >只有在属性AAA定义property后才能定义AAA.setter,AAA.deleterf1=<span >Foo()
f1.AAA
f1.AAA=<span >'<span >aaa<span >'
<span >del f1.AAA(
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> set_AAA(self,value): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">set的时候运行我啊</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> delete_AAA(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">delete的时候运行我啊</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)AAA</span>=property(get_AAA,set_AAA,delete_AAA) <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">内置property三个<a href="https://m.jb51.cc/tag/canshu/" target="_blank" >参数</a>与get,set,delete一一对应</span>
<span >
f1
f1.AAA
f1.AAA=<span >'<span >aaa<span >'
<span >del f1.AAA
怎么用?
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080"><a href="https://www.jb51.cc/tag/init/" target="_blank" >__init__</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> 原价</span> self.original_price = 100 <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> 折扣</span> self.<a href="https://www.jb51.cc/tag/dis/" target="_blank" >dis</a>count = 0.8<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">@property</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> price(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000">#</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"> 实际价格 = 原价 * 折扣</span> new_price = self.original_price *<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> self.<a href="https://www.jb51.cc/tag/dis/" target="_blank" >dis</a>count </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> new_price@price.setter</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> price(self,value): self.original_price </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> value@price.deleter</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> price(self): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">del</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> self.original_price
obj
=<span > Goods()obj.price <span >#<span > 获取商品价格
obj.price = 200 <span >#<span > 修改商品原价
<span >print<span >(obj.price)
<span >del obj.price <span >#<span > 删除商品原价3,classmethod=
@classmethod</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> func(cls): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">(cls.r<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>e)
Classmethod_Demo.func()
4,staticmethod=@stati<a href="https://www.jb51.cc/tag/cme/" target="_blank" >cme</a>thod</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">def</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> func(): </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">当<a href="https://www.jb51.cc/tag/putongfangfa/" target="_blank" >普通方法</a>用</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">)
Staticmethod_Demo.func()
总结
以上是内存溢出为你收集整理的python:类的基本特征------继承、多态与封装全部内容,希望文章能够帮你解决python:类的基本特征------继承、多态与封装所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)