码迷,mamicode.com
首页 > 其他好文 > 详细

第二十六天 组合 封装 多态

时间:2018-10-24 22:22:59      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:method   标准   严格   abs   直接   父类   隐藏   冗余   不能   

上节内容回顾:

  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 func1(self):
        print(Foo内的功能)

class Bar:
    bbb=2222
    def __init__(self,m,n):
        self.m = m
        self.n = n

    def func2(self):
        print(Bar内的功能)
obj1=Foo(10,20)
obj2=Bar(30,40)

obj1.xxx=obj2
print(obj1.x,obj1.y,obj1.aaa,obj1.func1)

print(obj1.xxx.m,obj1.xxx.n,obj1.xxx.bbb,obj1.xxx.func2)

组合另一个类中的多个对象

class OldboyPeple:
    school = Oldboy
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

class OldboyStudent(OldboyPleople):
    def choose_course(self):
        print(%s is choosing course%self.name)

class OldboyTeacher(OldboyPeople):
    def choose_course(self):
        stu,num=num
        print(老师%s给学生%s打分%s%(self.name,stu.name,num))

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

    def tell_course(self):
        print(课程名:<%s>价格:[%s] 周期:[%s]%(self.course_name,self.course_price,self.course_period))

python_obj = Course(python开发,3000,5mons)
linux_obj=Course(linux运维,5000,3mons)

stu1=OldboyStudent(egon,18,male)
stu1.course=[]
stu1.courses.append(linux_obj)
stu1.courses.append(python)obj)
stu1.courses[0].tell_course()

二.封装

1.什么是封装

  装指的是吧属性装进一个容器

  封指的是隐藏的意思,但是这种隐藏式对外不内的

2.为何要封装

  封装不是单纯意义的隐藏

  封装数据属性的目的:将数据属性封装起来,类外的使用就无法直接操作该数据属性了

  需要内部开一个接口给使用者,类的实际者可以在接口上附带任何逻辑,从而严格

  控制使用者对属性的操作

 

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

3.如何封装

  只要在属性前加上__开头,该属性就会被隐藏起来,该隐藏具备的特点:

    1.只要一种语法意义上的变形,即__开头的属性会在检测语法时发生变形,_类名__属性名.

    2.这种隐藏是对外不对内的,因为在类内部检测语法时所有的代码统一都会发生变形

    3.这种变形值在检测时发生一次,在类定义之后新增的__开头的属性并不会发生变形

    4.如果父类不想让子类覆盖自己的属性,可以在属性前加__开头.

#其实这仅仅这是一种变形操作且仅仅只在类定义阶段发生变形
#类中所有双下划线开头的名称如__x都会在类定义时自动变形成:_类名__x的形式:

class A:
    __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
    def __init__(self):
        self.__X=10 #变形为self._A__X
    def __foo(self): #变形为_A__foo
        print(from A)
    def bar(self):
        self.__foo() #只有在类内部才可以通过__foo的形式访问到.

#A._A__N是可以访问到的,
#这种,在外部是无法通过__x这个名字访问到。

内部调用

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.__card(self)
a.withdraw()

隐藏的属性可以被内部使用

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.__card(self)
a.withdraw()

三.property装饰器.

property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

  即:可以把函数结果作为属性被返回.

例一:BMI指数(bmi是计算而来,但很明显它听起来是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

 

成人的BMI数值:

过轻:低于18.5

正常:18.5-23.9

过重:24-27

肥胖:28-32

非常肥胖:高于32

  体质指数(BMI)=体重(kg)?身高2(m)

  EX:70kg ?(1.75??1.75) = 22.86

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,70,1.82)
obj.height=1.85

print(obj.bmi)

property的需要了解的用法

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

    @property
    def name(self)
        return<name:%s>self.name

    @name.setter
    def name(self,new_name):
        if type(new_name)is not str:
            print(名字必须是str类型")
            return
        self.__name=new_name
    
    @name.deleter
    def name(self)
        del self.name
obj=People(egon)
print(obj.name)

obj.name=123
print(obj.name)

def obj.name
print(obj.__dict__)

四.多态,

1.什么是多态

  同一事物的多种形态

2.为何要用多态

  多态性:指

import abc

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

# Animal() # 父类不能实例化,因为父类本身就是用来制定标准的
class People(Animal):
    def speak(self):
        print(say hello)
    # def jiao(self):
    #     print(‘say hello‘)

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

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


peo=People()
dog1=Dog()
pig1=Pig()
#
#
peo.speak()
dog1.speak()
pig1.speak()
def speak(animal):
    animal.speak()

speak(peo)
speak(dog1)
speak(pig1)

 

的是可以在不用考虑对象具体类型的前提下而直接使用对象的方法

3.如何用多态

 

第二十六天 组合 封装 多态

标签:method   标准   严格   abs   直接   父类   隐藏   冗余   不能   

原文地址:https://www.cnblogs.com/gongcheng-/p/9845919.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!