自学Python-13 面向对象编程(二、进阶篇)


自学Python-13 面向对象编程(二、进阶篇)

一个完整的示例,理解什么是封装、继承与多态


<code>class Animal:
"""
双下划线 表示属性私有,外部不能直接访问,但实际上Python
没有严格语法来限制外部真的不能访问,你仍然可以通过
animal.Animal__eye来直接访问,可以看出python只是对私
有属性改了个名称来限制我们的访问。这看起来比较矛盾,骆昊
前辈在这个问题上这样说,他说“因为绝大多数程序员都认为开放
比封闭要好,而且程序员要自己为自己的行为负责。”私有方法也
是用双下划线声明
"""
__eye = 2

"""
单下划线 只是暗示该属性为私有,不建议外接直接访问,但外部
还是可以直接通过animal._age访问,意思是:虽然我可以被访
问,但是,请把我视为私有变量,不要随意访问
"""

_age = 8

_leg = 2

def __init__(self, name):
self._name = name

"""
不管使用哪种方式定义私有属性,如果我们要访问可以通过getter和setter
来访问和修改,这其实就是封装的思想,将不需要外部知道的细节私有化,同
时提供一些可以被外部访问到的属性和方法,这样能很好的减少耦合,自己的
事情自己处理,避免干扰外部业务。
"""

# eye的getter-访问器
@property
def eye(self):
return self.__eye

# eye的setter-修改器
@eye.setter
def eye(self, eye):
self.__eye = eye

# leg的getter
@property
def leg(self):
return self._leg

"""
我们只为leg属性设置了访问器,没有设置修改器,因此leg在本类中是一个只
读属性,实际上我们可以在setter中检查参数合法性,减少出错可能性,或者
也可以做其他的处理,这也是封装的思想体现

"""

"""
定义一个动物叫的方法,方法和函数只是定义和叫法上的不同,没有大的歧
义。方法就是在类内部的函数
"""

def makeVoice(self):
print('%s是动物,会发出叫声' % self._name)

"""
staticmethod修饰类的静态方法,直接通过(类名.静态方法名调用)。纯粹
的功能性方法比较适合声明为静态方法,例如在动物类中有一个判断是不是动
物的静态方法,这个方法与本类中其他方法没有任何关联,这看起来有点像
java工具类中的静态方法一样。该方法放在其他类中或者是单独声明为一个类
外的函数也可以,但是那样不利于模块的划分,代码堆在一起会很乱。
"""
@staticmethod
def isAnimal(eye, leg):
# 我假设动物的眼睛不超过2 腿不超过4
if eye > 2 or leg > 4:
return False

"""
classmethod修饰类的类方法,直接通过(类名.类方法名调用)。内置date类
中的类方法就是个很好的示例。


@classmethod
def fromtimestamp(cls, t):
y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t)
return cls(y, m, d)

@classmethod
def today(cls):
t = _time.time()
return cls.fromtimestamp(t)

"""

# 定义一个宠物类 下面会操作多继承


class Pet:
def __init__(self, name):
self.__name = name

def sleep(self):
print('%s睡觉' % self.__name)

def makeVoice(self):
print('%s是宠物,会发出叫声' % self.__name)


# 单继承 Dog类继承自Animal类
class Dog(Animal):
def __init__(self, name):
# 调用父类构造方法
Animal.__init__(self, name)
# 子类可以定义自己的属性
self.__name = name
# 子类继承了父类的属性
print('继承父类的age属性:%s' % self._age) # 继承父类的age属性:8

# 子类重写父类的方法,表现出不同的行为
def makeVoice(self):
print('%s是狗,会发出汪汪汪的叫声' % self.__name)


# 子类有更多的能力
def watchDoor(self):
print('狗会看门')


dog = Dog('小黑')
dog.makeVoice() # 小黑是狗,会发出汪汪汪的叫声
# getter访问eye
print(dog.eye) # 2
# setter设置eye
dog.eye = 10
print(dog.eye) # 10
# 尝试修改只读属性-会报错的
# dog.leg = 4 # AttributeError: can't set attribute
# 访问下双下划线定义的eye属性

"""
多继承 Cat继承Animal类和Pet类
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指
定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含
方法。例如若Cat中未重写makeVoice方法,则调用时将调用的Animal中的
makeVoice方法
"""


class Cat(Animal, Pet):
def __init__(self, name):
Animal.__init__(self, name)
Pet.__init__(self, name)
self.__name = name

# 子类重写父类方法,表现出不同的行为

def makeVoice(self):
print('%s是猫,会发出喵喵喵的叫声' % self.__name)

/<code>


封装

将属性与方法私有化,对外提供接口统一访问。这一过程将不需要外部知道的细节隐藏起来,同时在类中可自由更改自身的业务逻辑,不与外部发生冲突,能很好的解耦。


继承

继承是一种在已有类的基础上去创建新类的方式。新建的类就叫做子类、或者派生类、衍生类,原始类就叫做父类、超类、基类。子类将继承父类提供的方法和属性,在此基础上子类可以定义自己特有的方法和属性。通过继承也可以增强代码复用,提高效率。


多态

子类通过重写父类的方法,表现出不同的形态。例如猫和狗都继承动物类,拥有动物类的makeVoice方法,但表现出了不同的叫声,这就是多态的体现。


分享到:


相關文章: