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

Posted 学一点也是好

tags:

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

一、组合

什么是组合?

就是一个类的属性 的类型 是另一个自定义类的 类型,也可以说是某一个对象拥有一个属性,该属性的值是另一个类的对象。

通过为某一个对象添加属性(这里的属性是另一个类的对象)的方式,间接将两个类关联整合,从而减少类与类之间的代码冗余

class A:
    pass
class B:
    pass
b = B()
b.a=A()

借用之前的代码进行改进:

技术分享图片
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(self):
        print(%s choosing course % self.name)

    def tell_all_course(self):
        print(学生[%s]选修的课程如下%self.name)
        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()
        print(**60)


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

    def tell_info(self):
        print(<课程名:%s 价格:%s 周期:%s%(self.c_name,self.c_perice,self.c_perice))


stu = OldboyStudent(zfj,18,male)
teh = OldboyTeacher(egon,19,femal,10)
# print(stu.__dict__)
python = Coures(python全栈开发,1900,5mons)
linux = Coures(linux架构师,100,3mons)

stu.courses.append(python)
teh.courses.append(python)
stu.tell_all_course()
teh.tell_all_course()
View Code

二、多态

多态指的是同一种类或者事物的不同形态

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

  多态性的精髓:统一

人,狗,猪都是同属于动物的,他们都具有说和跑的特点,将共同的特点剥离出来组成父类

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()

这里涉及到了抽象类,我们导入了abc模块,abc.ABCMeta 是一个metaclass,用于在Python程序中创建抽象基类。

在相应的方法之前一行加上@abstractmethod之后,从新的一行开始定义相应的方法。实现的方法就是一个抽象的方法,子类继承之后,如果需要用到的这个方法则必须用新的方法将其实现

总结一句话就是,抽象类不能实例化,子类必须实现(抽象)父类的所有抽象方法

Python崇尚鸭子类型:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的

技术分享图片
class Disk:
    def read(self):
        print(Disk read)

    def write(self):
        print(Disk write)


class Memory:
    def read(self):
        print(Mem read)

    def write(self):
        print(Mem write)


class Cpu:
    def read(self):
        print(Cpu read)

    def write(self):
        print(Cpu write)


obj1=Disk()
obj2=Memory()
obj3=Cpu()

obj1.read()
obj2.read()
obj3.read()
View Code

三、封装

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

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

封装:将类的属性与方法私有化,形成对内可见对外不可见

如何封装?

  在类内定义的属性前加_开头(没有_结尾)

技术分享图片
class Foo:
    # part1
    # __num = 1000

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

    # part3
    def __test(self): # 变形成_Foo_test
        print("test")

# part1
# foo = Foo()
# print(foo.__num)

# part2
# foo = Foo("*****")
# print(foo.__name)

foo = Foo()
foo._Foo__test()
View Code

想要访问被私有化的属性,需要在要访问的对象前面加_类名。方法名

四、property

property装饰器是用来将类内的函数属性伪装成数据属性的,里面有getter,setter、(deleter)方法

技术分享图片
class Car:
    def __init__(self, name, type):
        self.__name = name
        self.__type = type
    def __str__(self):
        return ">> " + self.__name + "" + self.__type + "】<<"

    # __name对外不可见,但外界需要访问,所以通过方法对外界间接性提供__name
    # 完成这类功能的方法称之为接口
    @property # name() => name
    def name(self):
        # 可以做一系列安全操作
        return self.__name
    # @name.getter
    # def name(self):
    #     return self.__name

    # @name.setter
    # def set_name(self, name):
    #    self.__name = name
    @name.setter
    def name(self, name):
       self.__name = name


car = Car("宝马", "7系")
# >> 宝马【7系】<<
print(car)

# 访问属性,带着()不够逼格
# print(car.name())
print(car.name)  # 取值:getter

# car.set_name("奥迪")
# car.set_name = "奥迪"  # 设置:setter
car.name = "奥迪"
print(car)
View Code

 

还要继续努力

以上是关于Python-面向对象(组合封装与多态)的主要内容,如果未能解决你的问题,请参考以下文章

python学习8_1 面向对象(继承多态封装)以及零散概念(组合,property,绑定方法与非绑定方法,反射,内置函数)

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

Python20期课堂总结-20180120day7-面向对象之继承组合多态封装等

Python面向对象之:三大特性:继承,封装,多态。

19.Python面向对象之:三大特性:继承,封装,多态。

面向对象之:封装,多态