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

在这里插入图片描述

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

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)

封装

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

继承

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

多态

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章