25 组合 多态 封装

Posted ouyang99-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了25 组合 多态 封装相关的知识,希望对你有一定的参考价值。

组合:

1 什么是组合

组合指得是某一个对象拥有一个属性,该属性的值是另外一个类的对象

2. 为何要用组合

通过为某一个对象添加属相(属相的值是另外一个类的对象)的方式,可以间接的将两个类关联/整合/组合到一起

3. 如何用组合

技术图片
class OldboyPeople:
  school = Oldboy

  def __init__(self,name,age,sex,):
    self.name = name
    self.age = age
    self.sex = sex

class OldboyStudent(OldboyPeople):
  def __init__(self, name, age, sex,score=0):
    OldboyPeople.__init__(self,name,age,sex)
    self.score = score
    self.courses=[]

  def choose_course(self):
    print(%s choosing course % self.name)

  def tell_all_course(self):
    print((学生[%s]选修的课程如下 %self.name).center(50,=))
    for obj in self.courses:
      obj.tell_info()



class OldboyTeacher(OldboyPeople):
  def __init__(self,name,age,sex,level):
    OldboyPeople.__init__(self,name,age,sex)
    self.level=level
    self.courses=[]

  def score(self,stu,num):
    stu.score=num

  def tell_all_course(self):
    print((老师[%s]教授的课程如下 %self.name).center(50,*))
    for obj in self.courses:
      obj.tell_info()


class Course:
  def __init__(self,c_name,c_price,c_period):
    self.c_name = c_name
    self.c_price = c_price
    self.c_period = c_period

  def tell_info(self):
    print(<课程名:%s 价钱:%s 周期:%s> %(self.c_name,self.c_price,self.c_period))

#创建课程对象
python=Course(python全栈开发,1900,5mons)
linux=Course(linux架构师,900,3mons)

#创建学生对象
stu1=OldboyStudent(刘二蛋,38,male)

#将课程添加到学生课程列表
stu1.courses.append(python)
stu1.courses.append(linux)

#显示学生所选课程
stu1.tell_all_course()



#创建老师对象
tea1=OldboyTeacher(egon,18,male,10)

#将课程添加到老师授课列表
tea1.courses.append(python)

#显示老师所授课程
tea1.tell_all_course()
用法实例

多态与多态性

1. 什么是多态

多态指的是同一种类/事物的不同状态

2 为什么要用多态

多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象
多态性的精髓:统一

3. 如何用多态

class Animal:
  def speak(self):
    pass

class People(Animal):
  def shuo(self):
    print(say hello)

class Dog(Animal):
  def jiao(self):
    print(汪汪汪)

class Pig(Animal):
  def chang(self):
    print(哼哼哼)


obj1=People()
obj2=Dog()
obj3=Pig()



def speak(animal):
  animal.speak()


speak(obj1)# obj1.speak()
speak(obj2)# obj2.speak()
speak(obj3)# obj3.speak()
#metaclass=abc.ABCMeta

#@abc.abstractmethod

#规定子类中一定要有父类的方法


import abc

class Animal(metaclass=abc.ABCMeta):
  @abc.abstractmethod
  def speak(self):
    pass

  @abc.abstractmethod
  def run(self):
    pass

# Animal() # 父类只是用来建立规范的,不能用来实例化的,更无需实现内部的方法

class People(Animal):
  def speak(self):
    print(say hello)

  def run(self):
    pass

class Dog(Animal):
  def speak(self):
    print(汪汪汪)

  def run(self):
    pass

class Pig(Animal):
  def speak(self):
    print(哼哼哼)

  def run(self):
    pass

obj1=People()
obj2=Dog()
obj3=Pig()

封装


1. 什么是封装

装:往容器中/名称空间里存名字

封:代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内

 

2 为什么要封装

# 封装数据属性:将数据属性隐藏起来,类外就无法直接操作属性,需要类内开辟一个接口来外部的使用可以间接地操作属性,可以在接口内定义任意的控制逻辑,
# 从而严格控制使用对属性的操作

3. 如何封装

在类内定义的属性前加__开头(没有__结果)
总结:
1. __开头的属性实现的隐藏仅仅只是一种语法意义上的变形,并不会真的限制类外部的访问
2. 该变形操作只在类定义阶段检测语法时发生一次,类定义阶段之后新增的__开头的属性并不会变形
3. 如果父类不想让子类覆盖自己的属性,可以在属性前加__开头

class Foo:
  __x=111 # _Foo__x
  __y=222 # _Foo__y

  def __init__(self,name,age):
    self.__name=name
    self.__age=age

  def __func(self): #_Foo__func
    print(func)

  def get_info(self):
    print(self.__name,self.__age,self.__x) #print(self._Foo__name,self._Foo__age,self._Foo__x)
#报错
print(Foo.__x)
print(Foo.__func)
print(Foo.__dict__)

#没报错
print(Foo._Foo__x)
print(Foo._Foo__y)
print(Foo.__dict__)

#类定义阶段之后新增的__开头的属性并不会变形
Foo.__z=333

print(Foo.__z) 

 

 

class People:
  def __init__(self,name,age):
    self.__name=name
    self.__age=age

  def tell_info(self):
    print(<name:%s age:%s> %(self.__name,self.__age))

  def set_info(self,name,age):
    if type(name) is not str:
      print(名字必须是str类型傻叉)
      return
    if type(age) is not int:
      print(年龄必须是int类型傻叉)
      return
    self.__name=name
    self.__age=age


obj=People(egon,18)
# obj.tell_info()
# obj.set_info(‘EGON‘,19)
# obj.set_info(123,19)
obj.set_info(EGON,18)
obj.tell_info()

# 封装函数属性:隔离复杂度

class ATM:
  def __card(self):
    print(插卡)
  def __auth(self):
    print(用户认证)
  def __input(self):
    print(输入取款金额)
  def __print_bill(self):
    print(打印账单)
  def __take_money(self):
    print(取款)

def withdraw(self):
  self.__card()
  self.__auth()
  self.__input()
  self.__print_bill()
  self.__take_money()

a=ATM()
a.withdraw()

property

 property装饰器是用来将类内的函数属性伪装成数据属性

技术图片
class People:
  def __init__(self,name,weight,height):
    self.name=name
    self.weight=weight
    self.height=height

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

obj=People(‘egon‘,80,1.83)
obj.height=1.85
obj.weight=75

#print(obj.bmi())
print(obj.bmi)
技术图片

 

 

 

# 了解....

技术图片
class People:

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

  @property
  def name(self):
    return ‘<名字:%s>‘ %self.__name

  @name.setter
  def name(self,obj):
    if type(obj) is not str:
      print(‘name必须为str类型‘)
      return
    self.__name=obj

  @name.deleter
  def name(self):
    print(‘不让删‘)
    del self.__name

obj=People(‘egon‘)
print(obj.name)
obj.name=‘EGON‘
obj.name=123
print(obj.name)

del obj.name
print(obj.__dict__)
技术图片

 

以上是关于25 组合 多态 封装的主要内容,如果未能解决你的问题,请参考以下文章

第二十六天 组合 封装 多态

组合,封装与多态

组合, 封装, 多态补充

组合,多态,封装

Python-面向对象(组合封装与多态)

python面向对象:组合封装property装饰器多态