精华内容
下载资源
问答
  • 分享给大家供大家参考,具体如下:目标多态面向对象三大特性封装 根据 职责 将 属性 方法 封装 到一个抽象 中定义的准则继承 实现代码的重用,相同的代码不需要重复的编写设计的技巧子类针对自己特有的...

    本文实例讲述了Python面向对象之多态原理与用法。分享给大家供大家参考,具体如下:

    目标

    多态

    面向对象三大特性

    封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中

    定义类的准则

    继承 实现代码的重用,相同的代码不需要重复的编写

    设计类的技巧

    子类针对自己特有的需求,编写特定的代码

    多态 不同的 子类对象 调用相同的 父类方法,产生不同的执行结果

    多态 可以 增加代码的灵活度

    以 继承 和 重写父类方法 为前提

    是调用方法的技巧,不会影响到类的内部设计

    多态案例演练

    需求

    1.在 Dog 类中封装方法 game

    普通狗只是简单的玩耍

    2.定义 XiaoTianDog 继承自 Dog,并且重写 game 方法

    哮天犬需要在天上玩耍

    3.定义 Person 类,并且封装一个 和狗玩 的方法

    在方法内部,直接让 狗对象 调用 game 方法

    案例小结

    Person 类中只需要让 狗对象 调用 game 方法,而不关心具体是 什么狗

    game 方法是在 Dog 父类中定义的

    在程序执行时,传入不同的 狗对象 实参,就会产生不同的执行效果

    多态 更容易编写出出通用的代码,做出通用的编程,以适应需求的不断变化!

    class Dog(object):

    def __init__(self, name):

    self.name = name

    def game(self):

    print("%s 蹦蹦跳跳的玩耍..." % self.name)

    class XiaoTianDog(Dog):

    def game(self):

    print("%s 飞到天上去玩耍..." % self.name)

    class Person(object):

    def __init__(self, name):

    self.name = name

    def game_with_dog(self, dog):

    print("%s 和 %s 快乐的玩耍..." % (self.name, dog.name))

    # 让狗玩耍

    dog.game()

    # 1. 创建一个狗对象

    # wangcai = Dog("旺财")

    wangcai = XiaoTianDog("飞天旺财")

    # 2. 创建一个小明对象

    xiaoming = Person("小明")

    # 3. 让小明调用和狗玩的方法

    xiaoming.game_with_dog(wangcai)

    希望本文所述对大家Python程序设计有所帮助。

    展开全文
  • PythonPython开发Python语言Python学习日记(二十五) 接口类、抽象类多态 接口类继承有两种用途:继承基类的方法,并且做出自己的改变或扩展(代码重用)声明某个子类兼容于某基类,定义一个接口类interface,接口类中...

    Python

    Python开发

    Python语言

    Python学习日记(二十五) 接口类、抽象类、多态

    接口类

    继承有两种用途:继承基类的方法,并且做出自己的改变或扩展(代码重用)和声明某个子类兼容于某基类,定义一个接口类interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口的功能

    比如说一种支付方式有三种不同的途径:Alipay、Applepay、Wechatpay

    如果现在只有两种支付方式Alipay和Wechatpay,我们该如何去实现支付的方法呢?

    classWechat:defpay(self,money):print('已经用了微信支付了%s元'%money)classAlipay:defpay(self,money):print('已经用了支付宝支付了%s元'%money)

    wechat=Wechat()

    wechat.pay(200) #已经用了微信支付了200元

    ali =Alipay()

    ali.pay(150) #已经用了支付宝支付了150元

    但是这样做有一点不好就是用户要去关心他在支付的时候是用什么方式去pay的,而我们只需要传一个支付的对象和钱就好了

    def pay(obj_pay,money): #定义一个支付函数

    obj_pay.pay(money)classWechat:defpay(self,money):print('已经用了微信支付了%s元'%money)classAlipay:defpay(self,money):print('已经用了支付宝支付了%s元'%money)

    wechat=Wechat()

    pay(wechat,300) #已经用了微信支付了300元

    ali =Alipay()

    pay(ali,250) #已经用了支付宝支付了250元

    这样写虽然可以,但是假设在之后添加了一个新的类Applepay的付款方式,里面的方法名和pay名不同就会导致报错

    from abc importabstractmethod,ABCMetaclass Payment(metaclass=ABCMeta):

    @abstractmethoddefpay(self,money):raiseNotImplementedclassWechat(Payment):defpay(self,money):print('已经用了微信支付了%s元'%money)classAlipay(Payment):defpay(self,money):print('已经用了支付宝支付了%s元'%money)classApple(Payment):defpayMoney(self,money):print('已经用了支付宝支付了%s元'%money)

    wechat=Wechat()

    ali=Alipay()

    apple= Apple() #Can't instantiate abstract class Apple with abstract methods pay

    这样的话如果开发人员写的方法名和pay不同时,程序在实例化对象就会报错就直接给给开发人员提示了要用规范的方法去写。如果我们再把Apple类中的方法给改回pay的方法名,那么就不会报错了

    classApple(Payment):defpay(self,money):print('已经用了支付宝支付了%s元'%money)

    apple= Apple()

    接口的多继承

    如果我们归纳下面三种动物的行为,老虎能走路、游泳;天鹅能飞、走路、游泳;老鹰能走路、飞,我们该如何用接口的方法去表示呢?

    from abc importabstractmethod,ABCMetaclass Swim_Behavior(metaclass=ABCMeta):

    @abstractmethoddefswim(self):pass

    class Walk_Behavior(metaclass=ABCMeta):

    @abstractmethoddefwalk(self):pass

    class Fly_Behavior(metaclass=ABCMeta):

    @abstractmethoddeffly(self):pass

    classTiger(Swim_Behavior,Walk_Behavior):defwalk(self):print('Can walk!')defswim(self):print('Can swim!')classSwan(Swim_Behavior,Walk_Behavior,Fly_Behavior):defwalk(self):print('Can walk!')defswim(self):print('Can swim!')deffly(self):print('Can fly!')classHawk(Walk_Behavior,Fly_Behavior):defwalk(self):print('Can walk!')deffly(self):print('Can fly!')

    t=Tiger()

    s=Swan()

    h= Hawk()

    接口类本身的方法不实现只是起到规范的作用

    接口隔离原则:

    使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口

    专门的接口指的是上面的动物能walk就用walk的接口,能fly就用fly的接口,能swim就用swim的接口

    不使用单一的接口指的是不应该使用一个接口里面既能有walk的行为又有fly的行为等,只有这样把每一个功能都隔离开,我们在后面用到这个功能就能够继承到它所有相关变量名和方法名

    即客户端不应该依赖那些不需要的接口指的是创建了一个Tiger类不应该要那些自己本身没有的类,比如fly

    抽象类

    抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

    如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性

    #在操作系统中一切皆文件

    from abc importabstractmethod,ABCMetaclass All_file(metaclass=ABCMeta):

    all_type= 'file' #所有的类型都是文件

    @abstractmethod #定义一个抽象方法无需实现功能

    defwrite(self):pass@abstractmethod#定义一个抽象方法无需实现功能

    defread(self):pass

    class Txt(All_file): #定义一个Txt类,子类继承抽象类,但是必须定义一个write和read的方法

    defwrite(self):print('Write something...')defread(self):print('Read something...')class Sata(All_file): #定义一个Sata类,子类继承抽象类,但是必须定义一个write和read的方法

    defwrite(self):print('Write something...')defread(self):print('Read something...')

    txt=Txt()

    sata=Sata()

    txt.read()#Read something...

    txt.write() #Write something...

    sata.read() #Read something...

    sata.write() #Write something...

    print(txt.all_type) #file

    print(sata.all_type) #file

    抽象类是一种规范,一般情况下单继承能实现的功能都是一样的,所以在父类中可以有一些简单的基础实现;多继承情况由于功能比较复杂,所以不容易抽象出相同的功能,具体实现写在父类中

    接口类和抽象类总结

    在python中没有接口类,但有抽象类;abc模块中的metaclass = ABCMeta,@abstractmethod它的本质是做代码的规范用的,希望子类中能实现父类名字完全一样的方法

    接口类和抽象类:

    从java的角度上看是有区别的,java本来就支持单继承所以就有了抽象类;java没有多继承,所以为了接口隔离原则,设计了接口这个概念,支持多继承了

    而python它既支持单继承也支持多继承,所以对于接口类和抽象类的区别就不会那么明显了,甚至在python中没有内置接口类

    多态

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

    python天生支持多态

    from abc importabstractmethod,ABCMetaclass Payment(metaclass=ABCMeta): #支付方式类

    @abstractmethoddefpay(self,money):pass

    class Wechat(Payment): #支付方式---微信支付

    defpay(self,money):print('已经用了微信支付了%s元'%money)class Alipay(Payment): #支付方式---支付宝支付

    defpay(self,money):print('已经用了支付宝支付了%s元'%money)class Apple(Payment): #支付方式---苹果支付

    defpay(self,money):print('已经用了支付宝支付了%s元'%money)

    多态性

    就是虽然是一类东西但是它们执行的是相同的方法但是做的是不同的事,比如微信它用的是微信支付、支付宝它用的是支付宝支付、苹果支付它用的是苹果支付...

    鸭子类型

    python语言里面有一个鸭子类型的概念,而在某些其他的属于强类型语言,用的是多态

    鸭子类型:不崇尚根据继承所得来的相似,我只是自己实现我自己的代码就可以了,如果有两个类它们刚好相似,并不产生父类的子类的兄弟关系,那这就是鸭子类型。像list、tuple这种相似,是自己写代码的时候约束的,而不是通过父类约束的

    内容来源于网络,如有侵权请联系客服删除

    展开全文
  • 前面学习了面向过程和面向对象的概念,又学习了Python类和对象的相关知识,其中面向对象最大的特征是:封装、继承和多态。本文就分3大块内容,分别来详细学习面向对象中的三大特征。封装封装的概念来自电气电子...

    前面学习了面向过程和面向对象的概念,又学习了Python中类和对象的相关知识,其中面向对象最大的特征是:封装、继承和多态。本文就分3大块内容,分别来详细学习面向对象中的三大特征。

    封装

    封装的概念来自电气电子元件,集成电路的一道工序,后来引用到面向对象的程序设计思想中。现实中处处可见封装的例子:比如你家的洗衣机。

    把一台洗衣机看做洗衣机类的一个实例,洗衣机里有标准洗、速洗、精洗、桶干燥、洁桶等多种功能。作为用户不需要知道这些功能内部的具体实现,需要某项功能只要选择对应的功能键即可。这就是洗衣机封装了以上多种功能。

    洗衣机-封装

    相似地,在面向对象中,封装,说白了就是一个类中抽象出来的静态数据(即属性)以及该类的一些功能(即方法)。这就是前面学习的对象的属性和方法。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。这是前面学习的访问权限,在封装特性中,访问权限非常重要。

    继承

    在现实生活中一说到继承,你一定会想到"子承父业"这个词。因为这种父子关系,儿子"平白无故地"从父亲那里得到了家产基业等。

    在面向对象的程序设计里,与此类似。假设A类继承自B类,则A类称为子类或派生类,B类称为父类,也叫基类、超类。那么A类就"子承父业",这里的"父业",就是父类中的属性和方法,如此,A类中自然就有了B类中的属性和方法。这种继承关系使得代码的复用性大大提高。

    Python 同样支持类的继承,如果一种语言不支持继承,类就没有什么意义。不同的开发语言,继承的支持程度不一样。Objective-C、Java等是单继承,而Python、C++等是支持多继承的。

    前面在学习python中类的定义时,当时这样解释说明:类的定义需要关键字class,class后面紧接着是类名,即ClassName,类名通常是大写开头的单词。紧接着是(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。表示类中的属性或方法。

    class ClassName(object):

    ·

    ·

    ·

    既然,python是支持多继承的,那么类名后面的()里,是可以有多个类的,即:(BaseClass1, BaseClass2, BaseClass3...)。需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索,即方法在子类中未找到时,从左到右查找基类中是否包含方法。注意:方法的查找顺序这一点要十分清楚。

    BaseClassName(基类名)这种写法必须与派生类定义在一个作用域内。通常,如果基类定义在另一个模块中时这一点非常有用:

    class ClassName(modname.BaseClassName):

    我们假设定义了三个类:Animal动物类,Dog狗类,Cat猫类,模块结构分别如下:

    单继承模块结构

    Animal源码如下:

    # 定义一个动物类Animal

    class Animal(object):

    legs = '' # 腿的数量

    color = '' # 毛色

    def eat(self):

    print("Animal吃东西")

    def sleep(self):

    print("Animal睡觉")

    def walk(self):

    print("Animal走路")

    Dog狗类,继承自Animal类,源码:

    from extends import animal

    # 定义一个狗类,继承自动物类Animal

    class Dog(animal.Animal):

    pass

    Cat猫类继承自Animal类,源码如下:

    from extends import animal

    # 定义一个猫类Cat,继承自动物类Animal

    class Cat(animal.Animal):

    pass

    测试模块extends_test.py,分别创建了一个猫类对象c、狗类对象d,分别调用c、d对象吃的方法eat(),源码如下:

    from extends import cat, dog

    # 创建一个猫类对象

    c = cat.Cat()

    # 调用吃的方法

    c.eat()

    print('------------------')

    # 创建一个狗类对象

    d = dog.Dog()

    # 调用吃的方法

    d.eat()

    运行结果:

    Animal吃东西

    ------------------

    Animal吃东西

    可以看到,都打印出了Animal类中eat()方法中的内容。这样我们通过继承关系,让Dog\Cat两个类什么也不写就有了父类中的所有的属性和方法。

    多继承

    我们假设定义了4个类:Animal动物类,哺乳动物类Mammal、Dog狗类,Cat猫类,模块结构分别如下:

    多继承模块结构

    Animal动物类,哺乳动物类Mammal两个类,将作为Dog狗类,Cat猫类的父类。

    Animal源码如下:

    # 定义一个动物类Animal

    class Animal(object):

    legs = '' # 腿的数量

    color = '' # 毛色

    def eat(self):

    print("Animal吃东西")

    def sleep(self):

    print("Animal睡觉")

    def walk(self):

    print("Animal走路")

    Mammal哺乳动物类,源码如下:

    # 定义一个动物类Mammal

    class Mammal(object):

    # 哺育幼崽的方法

    def feed(self):

    print("用母乳哺育幼崽子")

    Dog狗类,继承自Animal类,源码如下:

    from extends import animal, mammal

    # 定义一个狗类,继承自动物类Animal,哺乳动物类Mammal

    class Dog(animal.Animal, mammal.Mammal):

    pass

    Cat猫类继承自Animal类,源码如下:

    from extends import animal, mammal

    # 定义一个猫类Cat,继承自动物类Animal,哺乳动物类Mammal

    class Cat(animal.Animal, mammal.Mammal):

    pass

    测试模块extends_test.py,分别创建了一个猫类对象c、狗类对象d,分别调用c、d对象吃的方法eat(),源码如下:

    from extends import cat, dog

    # 创建一个猫类对象

    c = cat.Cat()

    # 调用吃的方法

    c.eat()

    # 调用Mammal类中的方法

    c.feed()

    print('------------------')

    # 创建一个狗类对象

    d = dog.Dog()

    # 调用Animal中吃的方法:eat()

    d.eat()

    # 调用Mammal类中的方法:feed()

    d.feed()

    运行结果:

    Animal吃东西

    用母乳哺育幼崽子

    ------------------

    Animal吃东西

    用母乳哺育幼崽子

    拓展

    在Java中,使用extend关键字表示继承,Object是Java中所有类的基类,仅支持单继承。例如:

    class A extend Object{

    }

    在Objective-C中,则使用:表示继承。NSObject是OC中所有类的基类,且仅支持单继承。例如:

    @interface MyClass : NSObject {

    int memberVar1; // 实体变量

    id memberVar2;

    }

    +(return_type) class_method; // + 开头表示类方法

    -(return_type) instance_method1; // - 开头表示实例方法

    接下来要学习的面向对象的多态,正是在继承的基础上才有的特性:当子类和父类有了相同名称的方法时,就是多态了。

    多态

    多态特性涉及到父子类以及父类之间同名函数的调用顺序问题,所以前面提到了:一定要注意Python在自定义类时,类名后面的()圆括号中父类的顺序。若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索,即方法在子类中未找到时,从左到右查找基类中是否包含方法。

    注意:方法的查找顺序这一点要十分清楚。

    使用上面同样的类,我们定义了4个类:Animal动物类,哺乳动物类Mammal、Dog狗类,Cat猫类,模块结构分别如下:

    多态-模块结构

    Animal动物类,哺乳动物类Mammal两个类,将作为Dog狗类,Cat猫类的父类。

    Animal源码如下:

    # 定义一个动物类Animal

    class Animal(object):

    legs = '' # 腿的数量

    color = '' # 毛色

    def eat(self):

    print("Animal吃东西")

    def sleep(self):

    print("Animal睡觉")

    def walk(self):

    print("Animal走路")

    Mammal哺乳动物类,源码如下:

    # 定义一个动物类Mammal

    class Mammal(object):

    def feed(self):

    print("用母乳哺育幼崽子")

    def eat(self):

    print("哺乳动物-吃东西")

    def sleep(self):

    print("哺乳动物-睡觉")

    def walk(self):

    print("哺乳动物-走路")

    Dog狗类,继承自Animal类,源码如下:

    from extends import animal, mammal

    # 定义一个狗类,继承自动物类Animal,哺乳动物类Mammal

    class Dog(animal.Animal, mammal.Mammal):

    def eat(self):

    print("小狗啃骨头")

    def sleep(self):

    print("小狗警惕地睡觉")

    def walk(self):

    print("小狗走路")

    Cat猫类继承自Animal类,源码如下:

    from extends import animal, mammal

    # 定义一个猫类Cat,继承自动物类Animal,哺乳动物类Mammal

    class Cat(animal.Animal, mammal.Mammal):

    def eat(self):

    print("小猫吃鱼")

    def sleep(self):

    print("小猫呼呼睡觉")

    def walk(self):

    print("小猫走猫步")

    可以看到,Animal动物类,哺乳动物类Mammal两个类,作为Dog狗类,Cat猫类的父类,并且每个类中都有同名不同实现的方法:eat()、sleep()、walk()。

    此时再在测试模块extends_test.py,分别创建了一个猫类对象c、狗类对象d,分别调用c、d对象吃的方法eat(),源码如下:

    from extends import cat, dog

    # 创建一个猫类对象

    c = cat.Cat()

    # 调用吃的方法

    c.eat()

    print('------------------')

    # 创建一个狗类对象

    d = dog.Dog()

    # 调用Animal中吃的方法:eat()

    d.eat()

    运行结果如下:

    小猫吃鱼

    ------------------

    小狗啃骨头

    子类的方法覆盖了父类中同名的方法,优先调用子类中同名的方法。

    假设,现在需要调用父类中的方法,而不是调用子类中的方法,则可以这么做:

    # 上接

    # 调用d对象父类中的eat()方法

    super(dog.Dog, d).eat()

    运行结果:

    Animal吃东西

    深入理解多态

    要理解什么是多态,我们首先要对数据类型再作一点说明。当我们定义一个class的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样。比如上面的用到的对象:

    my_list = list() # my_list 是list类型

    a = Animal() # a是Animal类型

    d = Dog() # d是Dog类型

    isinstance(对象, 类型)

    isinstance(变量, 类型)用来判断一个变量是否是该类型或其子类的实例。注意如果该对象是该类的子类的对象也返回True。

    # 创建一个猫类对象

    c = cat.Cat()

    # 判断猫对象c是否是Cat类型

    print('猫c是Cat类型:',isinstance(c, cat.Cat))

    # 判断猫对象c是否是Cat类型

    print('猫c是Animal类型:',isinstance(c, animal.Animal))

    运行结果:

    猫c是Cat类型: True

    猫c是Animal类型: True

    这和现实是匹配的:猫是猫类型,猫是动物。但是,反过来,动物是猫,就不行了。

    # 创建一个Animal动物对象

    a = animal.Animal()

    # 判断动物对象a是否是Cat类型

    print('动物a是Cat类型:', isinstance(a, cat.Cat))

    # 判断动物对象a是否是Animal类型

    print('动物a是Animal类型:', isinstance(a, animal.Animal))

    运行结果:

    动物a是Cat类型: False

    动物a是Animal类型: True

    知道了以上知识,我们再写一个方法:

    # 定义一个动物吃东西的方法

    def animal_eat(animal):

    animal.eat()

    # 调用动物吃东西的方法,传入不同的对象

    animal_eat(dog.Dog())

    animal_eat(cat.Cat())

    运行结果:

    小狗啃骨头

    小猫吃鱼

    至此发现什么没?如果没有,那么现在,如果我们再定义一个Wolf类型,也继承自Animal:

    from extends import animal, mammal

    # 定义一个狼类,继承自动物类Animal,哺乳动物类Mammal

    class Wolf(animal.Animal, mammal.Mammal):

    def eat(self):

    print("狼吃羊")

    def sleep(self):

    print("狼警惕地睡觉")

    def walk(self):

    print("狼飞奔")

    在测试模块extends_test.py,导入wolf模块,并创建一个wolf对象,源码如下:

    from extends import cat, dog, animal, wolf

    # 定义一个动物吃东西的方法

    def animal_eat(animal):

    animal.eat()

    animal_eat(dog.Dog())

    animal_eat(cat.Cat())

    # 传入狼对象

    animal_eat(wolf.Wolf())

    运行结果:

    小狗啃骨头

    小猫吃鱼

    狼吃羊

    你会发现,新增一个Animal的子类,不必对animal_eat()做任何修改,实际上,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。

    多态的好处

    多态的好处就是,当我们在需要传入Dog、Cat、Wolf……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Wolf……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有eat()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的eat()方法,这就是多态的好处。

    对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用eat()方法,而具体调用的eat()方法是作用在Animal、Dog、Cat还是Wolf对象上,由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保eat()方法编写正确,不用管原来的代码是如何调用的。

    拓展:静态语言 & 动态语言

    对于静态语言来说,例如Java,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用eat()方法。

    对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个eat()方法就可以了。例如,定义一个带有eat()方法的黑洞类:

    # 定义一个带有eat()方法的黑洞类

    class BlackHole(object):

    def eat(self):

    print("黑洞吞噬一切东西,包括光~")

    from extends import cat, dog, animal, wolf

    # 定义一个动物吃东西的方法

    def animal_eat(animal):

    animal.eat()

    # 传入黑洞对象

    animal_eat(BlackHole())

    运行结果:

    黑洞吞噬一切东西,包括光~

    这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。

    Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()方法,返回其内容。但是,许多对象,只要有read()方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()方法的对象。

    小结

    本文详细学习了Python中面向对象的3大特性:封装、继承、多态,以及拓展了python中的鸭子类型。这三大特性是任何面向对象语言的基础知识,要深刻理解。

    更多了解,可关注公众号:人人懂编程

    微信公众号:人人懂编程

    展开全文
  • python多态_Python多态

    2020-12-03 13:03:12
    面向对象三大特性封装根据职责将属性方法封装到一个抽象中定义的准则继承实现代码的重用,相同的代码不需要重复的编写设计的技巧子类针对自己特有的需求,编写特定的代码多态不同的子类对象调用相同的父类...

    面向对象三大特性

    封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中

    定义类的准则

    继承 实现代码的重用,相同的代码不需要重复的编写

    设计类的技巧

    子类针对自己特有的需求,编写特定的代码

    多态 不同的 子类对象 调用相同的 父类方法,产生不同的执行结果

    多态 可以 增加代码的灵活度

    以 继承 和 重写父类方法 为前提

    是调用方法的技巧,不会影响到类的内部设计

    多态案例演练

    需求

    在 Dog 类中封装方法 game

    普通狗只是简单的玩耍

    定义 XiaoTianDog 继承自 Dog,并且重写 game 方法

    哮天犬需要在天上玩耍

    定义 Person 类,并且封装一个 和狗玩 的方法

    在方法内部,直接让 狗对象 调用 game 方法

    案例小结

    Person 类中只需要让 狗对象 调用 game 方法,而不关心具体是 什么狗

    game 方法是在 Dog 父类中定义的

    在程序执行时,传入不同的 狗对象 实参,就会产生不同的执行效果

    多态 更容易编写出出通用的代码,做出通用的编程,以适应需求的不断变化!

    class Dog(object):

    def __init__(self, name):

    self.name = name

    def game(self):

    print("%s 蹦蹦跳跳的玩耍..." % self.name)

    class XiaoTianDog(Dog):

    def game(self):

    print("%s 飞到天上去玩耍..." % self.name)

    class Person(object):

    def __init__(self, name):

    self.name = name

    def game_with_dog(self, dog):

    print("%s 和 %s 快乐的玩耍..." % (self.name, dog.name)) # dog是wangcai # wangcai是XiaoTianDog的实例对象 # dog.name是调用父类方法

    # 让狗玩耍

    dog.game()

    # Person 类中只需要让 狗对象 调用 game 方法,而不关心具体是 什么狗

    # game 方法是在 Dog 父类中定义的

    # 在程序执行时,传入不同的 狗对象 实参,就会产生不同的执行效果

    # 1. 创建一个狗对象

    # wangcai = Dog("旺财")

    wangcai = XiaoTianDog("飞天旺财")

    # 2. 创建一个小明对象

    xiaoming = Person("小明")

    # 3. 让小明调用和狗玩的方法

    xiaoming.game_with_dog(wangcai)

    # 小明 和 飞天旺财 快乐的玩耍...

    # 飞天旺财 飞到天上去玩耍...

    展开全文
  • 继承有两种用途:继承基类的方法,并且做出自己的改变或扩展(代码重用)声明某个子类兼容于某基类,定义一个接口interface,接口中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口,并且实现接口...
  • 1,内容回顾 # 继承 : 什么是什么的关系 # 单继承 ***** # 先抽象再继承,几个类之间的相同代码抽象出来,成为父类 # 子类自己没有的名字,就可以使用父类的方法和... # 新式类和经典类: # 多继承寻找名字的...
  • 前言:python面向对象的三大特性:继承,封装,多态。1. 封装:把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想.具体的情况具体分析. 比如. 你写了⼀个...
  • 分享给大家供大家参考,具体如下:目标多态面向对象三大特性封装 根据 职责 将 属性 方法 封装 到一个抽象 中定义的准则继承 实现代码的重用,相同的代码不需要重复的编写设计的技巧子类针对自己特有的...
  • 昨日复习  派生方法派生属性  super想使用子类的对象调用父类的方法时,才使用super,注意super方法遵循mro,不能光看括号 ... 经典Python2 不继承object,查找名字遵循深度优先遍历算法  新式...
  • 1.封装 根据 职责 将 属性 方法 封装 到一个抽象 中  定义的准则 2.继承 实现代码的重用,相同的代码不需要重复的编写  设计的技巧  子类针对自己特有的需求,编写特定的代码 3.多态 不同的 子类对象...
  • 分享给大家供大家参考,具体如下:目标多态面向对象三大特性封装 根据 职责 将 属性 方法 封装 到一个抽象 中定义的准则继承 实现代码的重用,相同的代码不需要重复的编写设计的技巧子类针对自己特有的...
  •  2、声明某个子类兼容某基类,定义一个接口Interface,接口中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口,并且实现接口中的功能 class Alipay: # 支付宝支付 def pay(self...
  • 接口类和抽象类都是一种编程思想或者规范 从JAVA中而来 抽象类python原生支持的 接口类:python原生不支持 它们的目的是规范 java:java里的所有类的继承都是单继承,所以抽象类完美的解决了单继承需求中的...
  • 封装 根据 职责 将 属性 方法 封装 到一个抽象 中 定义的准则 继承 实现代码的重用,相同的代码不需要重复的编写 设计的技巧 子类针对自己特有的需求,编写特定的代码 多态 不同的 子类对象 调用...
  • 封装 根据 职责 将 属性 方法 封装 到一个抽象 中 定义的准则 继承 实现代码的重用,相同的代码不需要重复的编写 设计的技巧 子类针对自己特有的需求,编写特定的代码 多态 不同的 子类对象 调用相同的 ...
  • 六、Python面向对象--与对象\封装\继承\多态1、什么是面向对象编程1.1 程序设计的范式:程序可控,易于理解1.2 抽象并建立对象模型1.3 程序是不同对象相互调用的逻辑。每个对象在代码中抽象出来其实就是;描述...
  • 1、python中没有接口类,有抽象类(abc模块中的metaclass = ABCMeta,@abstructmethod) 2、接口类和抽象类本质是做代码规范用的,希望在子类中实现和父类方法名字完全一样的方法 3、在java的角度上看是有区别的  ...
  • Python面向对象之多态

    2019-05-06 20:37:00
    封装 根据职责将属性方法封装到一个抽象中;--定义的准则 继承 实现代码的重用,相同的代码不需要重复的编写;--设计的技巧;子类针对自己的需求,编写特定的代码; 多态 不同的子类对象调用相同的父类...
  • Python之继承与多态

    2020-02-10 20:25:04
    封装:根据职责将属性方法封装到一个抽象中。 继承:实现代码的重用,相同的代码不需要重复编写 多态:不同的对象调用相同的方法,产生不同的执行结果,增加代码灵活度 一. 单继承 应用场景: :Animal...
  • 封装:根据职责将属性方法封装到一个抽象中 继承:实现代码的重用,相同的代码不需要重复的写 “”" class Animal: def eat(self): print('吃~!!!!~~!!!!!~') def drink(self): print('喝~~~!!!!!...
  • 面向对象的主要好处之一是封装,通过封装一能够将各种实现封闭在的模块内...此外更主要还能够体现出多态,即根据对象的具体情况,对统一规范的使用表现出期望的不同行为,也使得对于对象的使用更易规范理解。 ...
  • 分享给大家供大家参考,具体如下:目标多态面向对象三大特性封装 根据 职责 将 属性 方法 封装 到一个抽象 中定义的准则继承 实现代码的重用,相同的代码不需要重复的编写设计的技巧子类针对自己特有的...
  • -- python是一种动态语言,默认支持多态,同一个方法 调用 不同的对象 ,执行的 结果各不相同;多态实现-- 继承:不同子类 继承 同一父类;-- 重写:子类重写 同一个方法,保证执行结果各不相同;示例-- 有如下...
  • 对象执行时的查询顺序是 对象>本>父类,分条分别进行.执行的函数跟定义的函数有...p1.name.append(1) #名称空间存储的是变量值的内存地址的关系 p1.name #[1] p2.name #[1] A.name #[1] p1.age = 12 p1.age .
  • 原标题:Python面向对象:封装和多态一、封装封装是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别。封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也...
  • 封装 根据 职责 将 属性 方法 封装 到一个抽象 中 1、定义的准则 继承 实现代码的重用,相同的代码不需要重复的编写 1、设计的技巧 2、子类针对自己特有的需求,编写特定的代码 多态 不同的 子类对象 ...
  • 接口就是一个规范,在python里没有接口这种数据类型,没有接口专门的语法但是 可以通过继承abc模块实现接口的功能 2.接口的应用 归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 666
精华内容 266
关键字:

python抽象类和多态

python 订阅