您的位置:首页 - 教程 - python - 正文
面向对象(一)

面向对象编程(Object Oriented Programming,OOP)
面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。
注:Java和C#来只支持面向对象编程,而python比较灵活即支持面向对象编程也支持函数式编程

面向对象三大特性:封装继承多态

一、封装

封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
调用被封装的内容时,有两种情况:

  1. 通过对象直接调用
  2. 通过self间接调用
#1. 通过对象直接调用
class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age
 
obj1 = Foo('morra', 18)
print obj1.name    # 直接调用obj1对象的name属性
print obj1.age     # 直接调用obj1对象的age属性
 
#2. 通过self间接调用
class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age
  
    def detail(self):
        print self.name
        print self.age
  
obj1 = Foo('morra', 18)
obj1.detail()  # Python默认会将obj1传给self参数,所以,此时方法内部的 self = obj1
 

综上所述,对于面向对象的封装来说,其实就是使用__init__方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。

二、继承

继承,就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。父类也叫基类,子类也叫派生类。

class Animals:              #基类
    def __init__(self, name):
        self.name = name
 
    def eat(self):
        pass
 
    def drink(self):
        pass
 
class Dog(Animals):         #派生类
    def __init__(self, name):
        self.name = name
 
    def bark(self):
        print('汪')
 
 
obj_dog = Dog('morra')
obj_dog.eat()
obj_dog.bark()

(1) 单继承

优先级是,先子类后父类

(2) 多继承

python可以同时继承多个类(C# java是不可以的)。
优先级是,先子类后父类,父类里面先左再右,广度优先。

#新式类的广度优先查找
class D(object):
    def bar1(self):
        print 'D.bar'
 
class C(D):
    def bar(self):
        print 'C.bar'
 
class B(D):
    def bar(self):
        print 'B.bar'
 
class A(B, C):
    def bar(self):
        print 'A.bar'
a = A()
# 执行bar方法时
# 查找顺序:A --> B --> C --> D
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
a.bar()

(3) 执行父类的构造方法

#方法一:super,通过python多继承的原则查找
class Animal:
    def __init__(self):
        print('A构造方法')
        self.ty = "动物"
 
class Cat(Animal):
    def __init__(self):
        print('B构造方法')
        self.n = "猫"
        super(Cat,self).__init__()  #执行父类的构造方法,推荐用super()
 
c = Cat()
print(c.__dict__)
 
# ---------
# B构造方法
# A构造方法
# {'n': '猫', 'ty': '动物'}
 
 
#方法二:Animal,直接指定基类(不建议使用)
class Animal:
    def __init__(self):
        print('A构造方法')
        self.ty = "动物"
 
class Cat(Animal):
    def __init__(self):
        print('B构造方法')
        self.n = "猫"
        Animal.__init__(self)       #不推荐
 
c = Cat()
print(c.__dict__)
 
# ---------
# B构造方法
# A构造方法
# {'n': '猫', 'ty': '动物'}

三、多态

Pyhon不支持Java和C#这一类强类型语言中多态的写法,但是原生多态,其Python崇尚“鸭子类型”。

python的“鸭子类型”:

class F1:
    pass
 
class S1(F1):
    def show(self):
        print 'S1.show'
 
class S2(F1):
    def show(self):
        print 'S2.show'
 
def Func(obj):
    print obj.show()
 
s1_obj = S1()
Func(s1_obj) 
 
s2_obj = S2()
Func(s2_obj) 

四、反射在面向对象里的应用

class Foo:
    def __init__(self,name):
        self.name = name    对象.属性=变量
        pass
 
    def show(self):
        pass
 
 
obj = Foo('morra')
 
r = hasattr(Foo, 'show')    #只能找类里的成员
print(r)  # True
 
r = hasattr(obj, 'name')   #在对象中可以找自己的属性,就是self.name中的name属性
print(r)  # True
 
r = hasattr(obj, 'show')    #对象中也可以找类的成员,是通过python里的类对象指针来实现的
print(r)  # True
 

m = __import__('s1',fromlist=True)      #通过反射获取模块
 
class_name = getattr(m,"Foo")       #在模块中获取Foo类
 
obj = class_name('morra')       #实例化
 
val = getattr(obj,'name')         #获取类中的name属性
 
print(val)

五、旧式类与新式类

  1. 在python2.x的版本才有新式类和旧式类之分。
  2. 旧式类定义class AA,新式类class AA(object)
  3. 在多重继承的查找和调用方法上,旧式类是深度优先,新式类是广度优先
  4. 所以对于python3的多层继承来说,因为都是新式类,总是从左到右,广度优先的方式进行。

(1) 定义形式

#python2.7中的旧式类
class AA():
    pass
 
a = AA()
print(type(a))      #<type 'instance'>
print(type(AA))     #<type 'classobj'>
 
 
#python2.7中的新式类
class AA(object):
    pass
 
a = AA()
print(type(a))      #<class '__main__.AA'>
print(type(AA))     #<type 'type'>
 
 
#python3中的新式类
class AA(object):
    pass
 
a = AA()
print(type(a))      ## <class '__main__.AA'>
print(type(AA))     # <class 'type'>

(2) 多重继承时的查找规则

#旧式类的深度优先查找
class D:
    def bar1(self):
        print 'D.bar'
 
class C(D):
    def bar(self):
        print 'C.bar'
 
class B(D):
    def bar(self):
        print 'B.bar'
 
class A(B, C):
    def bar(self):
        print 'A.bar'
 
a = A()
# 执行bar方法时
# 查找顺序:A --> B --> D --> C
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
a.bar()

#新式类的广度优先查找
class D(object):
    def bar1(self):
        print 'D.bar'
 
class C(D):
    def bar(self):
        print 'C.bar'
 
class B(D):
    def bar(self):
        print 'B.bar'
 
class A(B, C):
    def bar(self):
        print 'A.bar'
a = A()
# 执行bar方法时
# 查找顺序:A --> B --> C --> D
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
a.bar()

评论: