组合, 封装, 多态补充

一. 什么是组合

  对象的属性是另一个对象或者可以认为一个对象是另一个对象属性

  为什么使用组合?===> 减少代码的冗余

class Person:
    school = ‘oldboy‘

class Teacher(Person):
    def __init__(self,name,age,level,course):
        self.name=name
        self.age=age
        self.level=level
        #course是课程对象,表示老师教授的课程
        self.course=course

class Student(Person):
    def __init__(self,name,age,course):
        self.name=name
        self.age=age
        # course是课程对象,表示学生选的课程
        self.course = course

class Course:
    def __init__(self,course_name,course_price,course_period):
        self.name=course_name
        self.price=course_price
        self.period=course_period

  之前如果没有没有Course这个类,那学生和老师的数据属性中都有course_name,course_price,course_period 这三个属性,为了减少代码的冗余,我们再重新加一个Course类,那么老师和学生就可以将这个course来当做自己的属性来调用

什么时候用组合什么时候用继承呢, 当什么是什么的关系用继承, 什么有什么的关系用组合

二. 多态

  什么是多态? 多态就是一类事物的多种形态,动物有多种形态,比如人, 狗, 猪

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(‘say hello‘)

pig = Pig()
dog = Dog()
people = Pepple()
pig.speak()
dog.speak()
people.speak()

# 如果按上面这种方法调用的话程序有点冗长,我们 可以先定义一个调用speak的函数,因为上面三个类中有共同的speak方法,
def  Animal_speak(obj)
    obj.speak()

Animal_speak(pig)
Animal_speak(dog)
Animal_sspeak(people)

  现在假如有这么一种情况,当人, 猪, 狗叫的表示方法不同时,怎么办呢?这里呀,我们程序员约定俗称的可以借用模块abc,来实现统一化看下面例子:

# 用abc来实现接口的统一化,来约束代码,只要是我定义了speak这个方法,你只要是继承我,那你就得用speak这个方法,如果不用就会报错,通过这样的约束来完成多态,只要是这一类的方法,都可以进行调用,多态其实就是用来约束我子类该用什么方法
import abc
class Animal(metaclass=abc.ABCMeta):
    @ abc.abstractmethod
    def speak(self):
    pass

class Pig(Animal):
    def xxx(self)
        print(‘哼哼哼‘)

class Dog(Animal):
    def yyy(self)
        print(‘汪汪汪‘)

class People(Animal):
    def zzz(self):
        print(‘say hello‘)

  在Python中崇尚鸭子类型(只要走路像鸭子,(对象中有某个绑定方法),那你就是鸭子),么有什么东西可以约束我子类方法应该怎么去写,都是人为规定的,不规定想怎么写就怎么写(鸭子类型不需要继承)

3. 封装

  什么是封装?从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小狗,小猫一起装进麻袋,然后把麻袋口子封上

  如何隐藏, 把东西包进去之后,隐藏起来,外部访问不到

  如何用代码实现隐藏? 隐藏属性和隐藏方法     隐藏之后只有内部才能访问,外部访问不到

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

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

# 将name 隐藏起来
class Person:
    def __init__(self, name, age)
        self.__name = name
        self.age = age   def get_name(self)     # 指的是内部     return self.__name

p = Person(‘panshao‘, 18)
print(p.age)     # 18
print(p.name)    # 抛出错误     指的是外部

print(p.get_name())   # 正常打印出名字

  通过people.__dict__查看属性可以看到下面结果

通过上面的图可以清楚的看到隐藏的本质就是通过变形才隐藏了属性,我们试着打印下people._People__name,结果还真得到了名字.

封装属性是防止别人乱改,保证安全性,封装方法是隔离复杂度

什么时候属性变形了呢? 只要在类内部,以__变量名来命名的变量,都会被隐藏,会发生变形,在外部放入的__变量名是不进行隐藏的

class Person:
    def __init__(self, name, weight, height)
        self.name = name
        self.weight = weight
        self.height = height

    def bmi(self)
        return self.weight/(self.height**2)

p = Person(‘bgon‘, 80, 1.78)
print(p.bmi())

  我们可以通过p.bmi()来获取bmi的值, 但是仔细想一下,因为人的体重是变的,bmi肯定也会跟着会变,这里可以用@property装饰器,他可以将方法包装成数据属性,在调用bmi的时候不用加括号,但是这样还是有错误的,就是说p.bmi在外部不能重新被修改

property之setter和deleter

class Person:
    def __init__(self,name,height,weight):
        self.__name=name
        self.__height=height
        self.__weight=weight
    @property
    def name(self):
        return ‘[我的名字是:%s]‘%self.__name
    #用property装饰的方法名.setter
    @name.setter
    def name(self,new_name):
        # if not isinstance(new_name,str):
        if type(new_name) is not str:
            raise Exception(‘改不了‘)
        if new_name.startswith(‘sb‘):
            raise Exception(‘不能以sb开头‘)
        self.__name=new_name

    # 用property装饰的方法名.deleter
    @name.deleter
    def name(self):
        # raise Exception(‘不能删‘)
        print(‘删除成功‘)
        # del self.__name

p=Person(‘lqz‘,1.82,70)
# print(p.name)
# p.name=‘pppp‘
# p.name=‘xxx‘
#改不了,直接抛一异常
# p.name=999
# p.name=‘sb_nick‘   # 这两种方法都改不了

# print(p.name)

del p.name
print(p.name)

  

四. 封装的扩展性

#类的设计者
class Room:
    def __init__(self,name,owner,width,length,high):
        self.name=name
        self.owner=owner
        self.__width=width
        self.__length=length
        self.__high=high
    def tell_area(self): #对外提供的接口,隐藏了内部的实现细节,此时我们想求的是面积
        return self.__width * self.__length

#使用者
>>> r1=Room(‘卧室‘,‘egon‘,20,20,20)
>>> r1.tell_area() #使用者调用接口tell_area
400

#类的设计者,轻松的扩展了功能,而类的使用者完全不需要改变自己的代码
class Room:
    def __init__(self,name,owner,width,length,high):
        self.name=name
        self.owner=owner
        self.__width=width
        self.__length=length
        self.__high=high
    def tell_area(self): #对外提供的接口,隐藏内部实现,此时我们想求的是体积,内部逻辑变了,只需求修该下列一行就可以很简答的实现,而且外部调用感知不到,仍然使用该方法,但是功能已经变了
        return self.__width * self.__length * self.__high

#对于仍然在使用tell_area接口的人来说,根本无需改动自己的代码,就可以用上新功能
>>> r1.tell_area()
8000

  

原文地址:https://www.cnblogs.com/panshao51km-cn/p/11618767.html

时间: 2024-10-31 15:41:27

组合, 封装, 多态补充的相关文章

第二十六天 组合 封装 多态

上节内容回顾: 1.继承 ps:继承解决的是类与类之间的代码冗余问题 2.如何继承:先抽象 再继承 3.Python 中继承的特点: 1. 单继承 多继承 2. 新式类 经典类 今日内容: 1.组合 2.封装 3.多态 一.组合 1.什么是组合 一个对象的属性是来自另一外一个类的对象,称之为组合 2.为何用组合 组合也是用来解决类与代码冗余的问题 3.如何用组合 class Foo: aaa=1111 def __init__(self,x,y) self.x=x self.y=y def fu

组合,封装与多态

组合: 1.什么是组合? 组合指的是一个对象中的属性,是另一个对象. 2.为什么要使用组合? 组合目的和继承一样, 为了减少代码冗余. 3.如何使用组合: 封装(夺命三问): 1.什么是封装? 比喻: 封: 比如把一个袋子封起来. 装: 比如把一堆小猫,小狗,nick装到袋子里. 封装指的是把一堆属性(特征与技能)封装到一个对象中. 存数据的目的是为了取, 对象可以"."的方式获取属性. 比喻: 对象就好比一个袋子, 袋子里面装一堆属性. 2.为什么要封装? 封装的目的为了方便存取,可

JavaScript基础--面向对象三大特性(八):继承封装多态

一.构造函数基本用法:function 类名(参数列表){属性=参数值} 1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 } 5 6 //创建Person对象的时候,可以直接给名字和年龄 7 var p1 = new Person('abc',80); 8 window.alert(p1.name); 9 var p2 = new Person('hello',9); 10 window.alert(p2.

封装,多态,继承. super的方法,类的约束,

1.python的三大特性:python的三大特性,封装,多态,继承封装:函数 模块 类 对象多态 : python中默认支持多态继承: python中的子类继承父类属性和方法 鸭子类型: 看着像鸭子,它就是鸭子python中处处都是鸭子 # 两者之间没有任何关系,但是都遵循着一个隐形的标准两个类中的鸭子类型:# 优点:1,统一标准,减少了词汇量# 2,两者之间没有任何耦合性,但是可以产生关系,其中一个的对象可以调用另一个类的方法# 其他例子 :index pop clear 2. super的

Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)

Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装: ? ? ? ? ? ?将一些东西封装到一个地方,你还可以取出来 ? ? ? ? ? ?类设置静态属性, 设置一些方法 或者 对象, 对象可以在其对象封装一些属性 多态: ? ? ? ? ? ?python默认支持多态, 多态指的是一种事务具有多种形态 ? ? ? ? ? ?1.多态可以增加代码的灵活度: ? ? ? ? ? ?2.以继承和重写父类方法为前提: ?

组合,多态,封装

一.组合 组合指的是某一个对象拥有一个属性,该属性的值是另一个对象 如下 class Foo: pass class Bar(): pass obj = Foo() obj.attr = Bar() 通过为某一个对象添加属性(属性的值为另一个对象)的方式,可以间接地将两类关联/整合到一起,从而减少类与类之间的代码冗余. 案例如下: class Person: def __init__(self, name, age, sex): self.name = name self.age = age s

Python之面向对象的组合、多态、菱形问题、子类中重用父类的两种方式

一.组合 ''' 1.什么是组合 组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象 2.为何用组合 组合也是用来解决类与类直接代码冗余问题的 3.如何用组合 ''' # 继承减少代码冗余,但是将类与类进行了强耦合,python不崇尚,所以能不用继承就尽量不用继承 class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age se

面向对象之:封装,多态

python面向对象的三大特性:继承,封装,多态. 1. 封装: 把很多数据封装到一个对象中. 把固定功能的代码封装到一个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如. 你写了一个很牛B的函数. 那这个也可以被称为封装. 在面向对象思想中. 是把一些看似无关紧要的内容组合到一起统一进行存储和使用. 这就是封装. 2. 继承: 子类可以自动拥有父类中除了私有属性外的其他所有内容. 说白了, 儿子可以随便用爹的东西. 但是朋友们, 一定要认清楚一个事情.

封装 多态 类的约束 super

python面向对象的三大特性:继承,封装,多态. 1. 封装: 把很多数据封装到?个对象中. 把固定功能的代码封装到?个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如. 你写了?个很?B的函数. 那这个也可以被称为封装. 在?向对象思想中. 是把?些看似?关紧要的内容组合到?起统?进?存储和使?. 这就是封装. 2. 继承: ?类可以?动拥有?类中除了私有属性外的其他所有内容. 说?了, ??可以随便?爹的东?. 但是朋友们, ?定要认清楚?个事情.