zoukankan      html  css  js  c++  java
  • 组合、多态和封装

    组合

    组合的概念

    组合指的是,在一个类中以另一个类的对象作为数据属性,称为类的组合,即对象的某个属性是另一个类的对象

    class Weapon:
        def knief(self):
            print('这是一把刀')
    
    class Person:
        def __init__(self, name):
            self.name = name
            self.weapon = Weapon()
    
    per = Person('人')
    per.weapon.knief()
    
    # 这是一把刀
    

    为什么使用组合

    通过组合可以减少代码冗余

    没有使用组合,学生和老师的课程的名称/价格/周期都要重新输入

    class Person:
        school = 'oldboy'
    
    class Teacher(Person):
        def __init__(self, name, age, course_name, course_price, course_period):
            self.name = name
            self.age = age
            self.course_name = course_name
            self.course_price = course_price
            self.course_period = course_period
    
    class Student(Person):
        def __init__(self, name, age, course_name, course_price, course_period):
            self.name = name
            self.age = age
            self.course_name = course_name
            self.course_price = course_price
            self.course_period = course_period
    

    使用组合,就可以把课程名称/价格/周期单独写在外面

    class Person:
        school = 'oldboy'
    
    class Teacher(Person):
        def __init__(self, name, age, course):
            self.name = name
            self.age = age
            self.course = course
    
    class Student(Person):
        def __init__(self, name, age, course):
            self.name = name
            self.age = age
            self.course = course
    
    class Course:
        def __init__(self, course_name, course_price, course_period):
            self.course_name = course_name
            self.course_price = course_price
            self.course_period = course_period
    
    course = Course('Python', 20100, 7)
    stu1 = Student('张三', 19, course)
    tea1 = Teacher('李四', 27, course)
    print(stu1.course.name)
    
    # Python
    

    小结

    组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同。

    1. 继承的方式

    通过继承建立了子类和父类之间的关系,它是一种"是"的关系,比如白马是马。

    当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生也是人。

    1. 组合的方式

    用组合的方式建立了类与组合的类之间的关系,它是一种"有"的关系,比如老师有学生1、学生2,老师有课程python、课程Linux

    当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

    多态和多态性

    多态

    多态指的一类事物有多种形态

    比如动物有多种形态:人,狗,猪

    class Animal:
        def speak(self):
            pass
    
    class Pig(Animal):
        def speak(self):
            print('哼哼哼')
    
    class Dog(Animal):
        def speak(self):
            print('汪汪汪')
    
    class People(Animal):
        def speak(self):
            print('嘤嘤嘤')
    

    多态性

    多态性是指在不考虑实例类型的情况下使用实例

    class Animal:
        def speak(self):
            pass
    
    class Pig(Animal):
        def speak(self):
            print('哼哼哼')
    
    class Dog(Animal):
        def speak(self):
            print('汪汪汪')
    
    class People(Animal):
        def speak(self):
            print('嘤嘤嘤')
    
    pig = Pig()
    dog = Dog()
    people = People()
    pig.speak()
    dog.speak()
    people.speak()
    
    # 哼哼哼
    # 汪汪汪
    # 嘤嘤嘤
    
    # 也可以定义一个统一的接口来使用
    def func(obj):
        obj.speak()
    

    多态性的好处

    1. 增加了程序的灵活性
    2. 增加了程序的可扩展性

    约束代码的两种方式

    方式一

    用abc模块实现接口统一化,约束代码(用的比较少)

    import abc
    class Animal(metaclass=abc.ABCMeta):   # 在括号中写metaclass=abc.ABCMeta
        @abc.abstractmethod   # 在要约束的方法上,写@abc.abstractmethod装饰器
        def speak(self):
            pass
    
    class Pig(Animal):
        def speak(self):
            print('哼哼哼')
    
    pig = Pig()
    pig.speak()
    

    方式二

    用异常处理来实现(常用)

    class Animal(self):
        def speak(self):
            raise Exception('重写方法')
    
    class Pig(Animal):
    	def speak(self):
    		print('哼哼哼')
    
    pig = Pig()
    pig.speak()
    

    鸭子类型

    Python崇尚鸭子类型,即"如果看起来像,叫声像而且走起路来像鸭子,那么它就是鸭子"。Python程序员通常根据这种行为来编写程序的。

    封装

    封装就好像是拿来一个麻袋,把小猫、小狗,一起装进麻袋,然后把麻袋封上口子。按照这种逻辑,封装="隐藏",这种理解是相当片面的。

    封装不是单纯意义的隐藏

    隐藏属性/方法:隐藏之后,外部访问不到,只有内部能够访问。

    隐藏属性:通过__变量名来隐藏

    隐藏方法:通过__方法名来隐藏

    隐藏属性:将数据隐藏起来这不是目的。隐藏起来然后对外提供操作该数据的接口,然后我们可以在接口附加上对该数据操作的限制,以此完成对数据属性操作的严格控制,是为了安全。

    通过变性隐藏了属性。什么时候属性变性:只要在类内部,以__变量名命名的变量,都会被隐藏,会发生变性,在外部放入的__变量名属性是不隐藏的

    隐藏方法:目的是隔离复杂度,提升安全性

    封装与扩展性

    封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;而外部使用者只知道一个借口,只要这个接口名、参数不变,使用者的代码永远无需改变。这就提供一个良好的合作基础——或者说,只要接口这个基础约定不见,则代码改变不足为虑。

    property特性

    property装饰器:把方法包装成数据属性

    将一个类的方法定义成数据属性后,对象再去使用的时候,无法察觉自己是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则。

  • 相关阅读:
    gcc -I -L -l区别
    如何在LINUX中开机、登陆、退出、定时、定期自动运行程序
    4B/5B编码原理
    powerpc平台移植zebra或quagga-0.99.23
    ubuntu 命令配置ip 网关 dns
    ubuntu新机安装工具
    svn add --no-ignore
    SSL handshake failed: SSL error: Key usage violation in certificate has been detected.
    netif_start_queue/netif_wake_queue/netif_stop_queue
    Linux系统中提示/usr/bin/ld: cannot find -lxxx错误的通用解决方法
  • 原文地址:https://www.cnblogs.com/yunluo/p/11426433.html
Copyright © 2011-2022 走看看