二十一、 Python 面向对象基础(一)self 、继承、封装
一:self 指针
self 形式参数, python 内部传递. self 指代对象的内存地址
1 class oldboy: 2 def fetch(self): 3 print(self) 4 5 obj1 = oldboy() 6 print(obj1,obj1.fetch()) 7 8 obj2 = oldboy() 9 print(obj2,obj2.fetch()) 10 11 12 C:\Python35\python.exe D:/python/day8/pr.py 13 <__main__.oldboy object at 0x00AD95D0> 14 <__main__.oldboy object at 0x00AD95D0> None 15 <__main__.oldboy object at 0x00AD9D30> 16 <__main__.oldboy object at 0x00AD9D30> None
二、 封装
将内容封装到某处,以后再去调用内封装在某处的内容。 对向对象封装来说,其实就是将构造方法将内容封装到对象。然后通过self 间接或者通过对象获取被封装的内容
所以在使用面向对象的封装特性的时候,需要:
- 将内容封装在某处
- 从某处调用被封装的内容
第一步: 将内容封装到某处
1 class Foo: 2 3 #构造方法,根据类创建对象时候自动执行 4 def __init__(self,name, age): 5 self.name = name 6 self.age = age 7 8 # 执行init方法, 将yy 和18 封装到 obj1(self) 的 name 和age 9 obj1 = Foo('yy',18) 10 11 # 执行init方法, 将xx 和18 封装到 obj2(self) 的 name 和age 12 obj2 = Foo('xx',18) 13 14 #self 是形式参数,当执行obj1 = Foo()的时候,self 相当于obj1 15 #所以其实内容就被封装到了 obj1 。 每个对象都有name 和 age
第二步:从某处调用
调用被封装的内容时,有2个情况
- 通过对象直接调用
- 通过self间接调用
1:通过对象直接调用
1 print(obj1.name) 2 print(obj2.name)
2:通过self间接调用
执行类中的方法,通过self 间接将调用的封装的内容
1 class Foo: 2 3 #构造方法,根据类创建对象时候自动执行 4 def __init__(self,name, age): 5 self.name = name 6 self.age = age 7 8 def detail(self): 9 print(self.name) 10 print(self.age) 11 12 # 执行init方法, 将yy 和18 封装到 obj1(self) 的 name 和age 13 obj1 = Foo('yy',18) 14 15 # 执行init方法, 将xx 和18 封装到 obj2(self) 的 name 和age 16 obj2 = Foo('xx',18) 17 18 obj1.detail() 19 20 obj2.detail()
三、继承
继承、面向对象中的继承和显示生活中的继承相同,子可以继承父的内容
对于面向对象继承来说,其实就是将多个类共有的方法提取到父类中。子类仅需继承父类而 不必一一实现
除了父类和子类的称谓,也可以称谓 派生类 和 基类
1 单继承
如果子类和父类有相关的方法。优先子类方法
1 class Animal: 2 3 def eat(self): 4 print('%s 吃'%self.name) 5 6 7 class cat(Animal): 8 def __init__(self,name): 9 self.name = name 10 11 class dog(Animal): 12 def __init__(self,name): 13 self.name = name 14 15 16 cats = cat('猫') 17 cats.eat() 18 19 dogs = dog('够') 20 dogs.eat()
2、多继承
1: 2个父系没有共同节点 深度优先 子类 -- > 左父类 -- 左爷爷 -- >右父类 -- > 右爷爷
2: 2个父系有共同节点 广度优先 子类 -- > 左父 -->右父 -- > 爷爷
3: 在执行中,针对每一个调用的函数,都从子类开始查找。 例如在子类在爷爷f1(),又调用了 f2(), 本质为self.f2(),self 为子类 对象。因此将从子类开始重新查找f2()
前面2个情况

三、多态
Python不支持多态,也不用到多态,多态的概念应用JAVA
其他语言需要指定对象的类型。
1 class F1: 2 pass 3 4 5 class S1(F1): 6 def show(self): 7 print 8 'S1.show' 9 10 11 class S2(F1): 12 def show(self): 13 print 14 'S2.show' 15 16 17 # 由于在Java或C#中定义函数参数时,必须指定参数的类型 18 # 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类 19 # 而实际传入的参数是:S1对象和S2对象 20 21 def Func(F1 obj): 22 """Func函数需要接收一个F1类型或者F1子类的类型""" 23 24 print 25 obj.show() 26 27 s1_obj = S1() 28 Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show 29 30 s2_obj = S2() 31 Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show 32 33 Python伪代码实现Java或C # 的多态
Python 不需要制定类型
1 class F1: 2 pass 3 4 5 class S1(F1): 6 7 def show(self): 8 print 'S1.show' 9 10 11 class S2(F1): 12 13 def show(self): 14 print 'S2.show' 15 16 def Func(obj): 17 print obj.show() 18 19 s1_obj = S1() 20 Func(s1_obj) 21 22 s2_obj = S2() 23 Func(s2_obj) 24 25 Python “鸭子类型”
四、基类构造方法
1:类名称后加()自动执行__init__
2: 使用super 可以执行父类构造方法
3:可以通过A.__init__ 直接执行父类的构造方法。
class A: def __init__(self): print('A构造方法') self.ty = 'A' class B(A): def __init__(self): print('B构造方法') self.n = 'B' #super执行父类构造方法 super(B,self).__init__() #也可以直接执行 A.__init__(self) #类名称后面加()自动执行 b = B()
总结:
面向对象是一种变成方式,此编程方式实现基于对类和对象的使用
类是一个模板,模板中包装了多个函数,共同使用
对象,根据模板创建的实例,实例用于调用被封装在类中的函数
面向对象的三个特性:封装、继承、多态
类以及类的方法在内存中仅有一份,根据类创建的每一个对象在内存中需要存一份
在创建对象时,对象中除了封装name,age 等属性外,还会保存一个对象指针,指向当前对象的类
通过对象.xxxx 执行的时候:
1:根据当前对象中的类对象指针找到类中的方法
2:将对象obj1 当做参数传递给方法的第一个参数self
扩展:
重载:函数名相同,参数个数不同(Python不支持)
重写:派生类中实现了基类的方法

浙公网安备 33010602011771号