二十一、 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不支持)

   重写:派生类中实现了基类的方法

posted @ 2016-06-18 22:24  咖啡茶  阅读(189)  评论(0)    收藏  举报