python之面向对象中的多态

直接看代码:

class Dog:
    def __init__(self,name):
        self.name = name
    def play(self):
        print("%s在汪汪汪" % self.name)
class SonDog(Dog):
    def play(self):
        print("%s不仅会汪,还会飞" % self.name)
class Person:
    def __init__(self,name):
        self.name = name
    def game(self,dog):
        print("%s正在和%s快乐地做游戏" % (self.name,dog.name))
        dog.play()

wc = Dog("旺财")
p = Person("妞妞")
p.game(wc)

输出:

说明:SonDog继承了Dog,并重写了play方法 。在Person类中,game方法需要传入一个Dog的实例。

假设我们传给game的不是Dog类,而是其子类,那么效果又是怎么样的呢?

# wc = Dog("旺财")
sonWc = SonDog("旺财儿子")
p = Person("妞妞")
p.game(sonWc)

输出:

我们发现,调用的是子类的play方法。

在python中,多态体现得没那么明显。我们可以将其展开来看。python是一门动态语言,不需要指定变量的类型,会在运行阶段自动判别变量的类型。因此,对于某个类而言,在实例化时,不需要指定它是什么类,比如说在java中有Dog这么一个类,在新建它的实例时,都会使用Dog dog = new Dog(),而在python中只需要dog = Dog()。 而所谓的多态,就是父类的引用指向子类的对象,拿java举例:SonDog继承了Dog,在实例化时Dog dog = new SonDog(),这就体现了一种多态性。为什么这么说?假设有多个不同的子类继承了该类,那么,该父类的引用指向不同子类的实例,就可以实现不同的功能。这就是多态的思想。

再拿本段代码而言,在Person类中的game方法,需要传入的是一个Dog对象(python并不用显示的指定它的类型),当传入wc时很好理解,但是,为什么还可以传入sonWc?之前也说过了,可以这么理解:Dog sonWc = new SonDog("旺财儿子"),这不就是父类的引用指向子类的对象了么。子类重写了父类的play方法,在调用时,会调用子类的play方法。

那么,假设父类中有而子类没有,子类中有而父类中没有的方法会怎么样呢?

class Dog:
    def __init__(self,name):
        self.name = name
    def play(self):
        print("%s在汪汪汪" % self.name)
    def test1(self):
        print("父类的test1方法")
class SonDog(Dog):
    def play(self):
        print("%s不仅会汪,还会飞" % self.name)
    def test2(self):
        print("子类的test2方法")
class Person:
    def __init__(self,name):
        self.name = name
    def game(self,dog):
        print("%s正在和%s快乐地做游戏" % (self.name,dog.name))
        dog.play()
        dog.test1()
        dog.test2()

# wc = Dog("旺财")
sonWc = SonDog("旺财儿子")
p = Person("妞妞")
p.game(sonWc)

输出:

假设,我们传入的就是父类的实例:

wc = Dog("旺财")
# sonWc = SonDog("旺财儿子")
p = Person("妞妞")
p.game(wc)

输出:

父类就访问不到子类的特有的方法。

讲这么一个是为了说明什么,多态使得父类可以访问到子类的方法和属性,虽然在python中并不显得那么明显。

总结:

  • 本文通过例子讲述了python中的多态:父类的引用指向子类的对象。
  • 另外,像方法的重写和重载也是多态的一种体现。

原文地址:https://www.cnblogs.com/xiximayou/p/12144509.html

时间: 2024-10-20 19:20:39

python之面向对象中的多态的相关文章

PHP面向对象中的多态示例

PHP不支持重载实现多态,所以PHP中的多态较其他语言中的多态可能是个假的"多态" 而PHP中我们使用回调函数这种方法可以实现PHP中的"多态" 演示场景:用户登录 一般而言网站分为前后台,那么前后端都有一套登录系统 ,前台的为用户登录 ,后台的为管理员登录. 此时我们就能将登录方法抽离出来写成一个公共的方法  不管是前台还是后台用户登录时都调用同一个方法,这样使得登录方法具备高重用性与高扩展性 以下演示代码为原生PHP编写(本演示代码只是提供思路并无具体业务逻辑处

设计模式-Template(行为模式) 采用 继承的方式 将算法封装在抽象基类中,在子类中实现细节。利用面向对象中的多态实现算法实现细节和高层接口的松耦合。

以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Template.h class AbstractClass { public: virtual ~AbstractClass(); void TemplateMethod(); protected: virtual void PrimitiveOperation1() = 0; virtual void PrimitiveOperation2() = 0; AbstractClass(); private: }; c

java中实现多态的机制是什么?

多态性是面向对象程序设计代码重用的一个重要机制,我们曾不只一次的提到Java多态性.在Java运行时多态性:继承和接口的实现一文中,我们曾详细介绍了Java实现运行时多态性的动态方法调度:今天我们再次深入Java核心,一起学习Java中多态性的实现. “polymorphism(多态)”一词来自希腊语,意为“多种形式”.多数Java程序员把多态看作对象的一种能力,使其能调用正确的方法版本.尽管如此,这种面向实现的观点导致了多态的神奇功能,胜于仅仅把多态看成纯粹的概念. Java中的多态总是子类型

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

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

python中的多态

# -*- coding: cp936 -*- #python 27 #xiaodeng #python中的多态 #多态:一个操作的意义取决于被操作对象的类型,相同的消息给予不同的对象会引发不同的动作. #多态意味着变量并不知道引用的对象是什么,根据引用对象的不同表现不同的行为方式 #在处理多态对象时,只需要关注他的接口即可 #同一个操作作用于不同的对象,可以有不同的解释,产生不同的执行结果. #多态案例1 #同样的+号可以用不同的对象相加,体现了多态的功能 print 1+2 print 'h

面向对象中的接口和多态

接口的作用是用来制定规范,以便让后面的程序根据这个规范来实现. 接口的声明方式:interface 接口名{},接口只能声明抽象方法,至少要有一个,但是声明的抽象方法前不需要用abstract修饰. 声明一个类实现接口,class demo implements interface_name {},当一个类实现接口的时候,这个类必须实现接口里定义的所有抽象方法.一个类可以既同时继承一个类又实现多个接口,class demo2 extends demo implements interface1,

python 面向对象——继承与多态

Python是面向对象的编程语言,面向对象的基本单元是类 类的声明: 1 class class_name(): 2 pass 测试如下: In [1]: class c(): ...: pass ...: In [2]: a=c() In [3]: a Out[3]: <__main__.c instance at 0x07500A30> 类的继承: 1 In [4]: class base(): 2 ...: def f(self): 3 ...: print 'base' 4 ...:

Python面向对象中的“私有化”

Python面向对象中的“私有化” Python并不直接支持私有方式,而要靠程序员自己把握在外部进行特性修改的时机. 为了让方法或者特性变为私有(从外部无法访问),只要在它的名字前面加上双下划线即可. 由双下划线 __ 开始的属性在运行时被“混淆”,所以直接访问是不允许的. 实际上,在 Python 带有双下划线的属性或方法并非正真意义上的私有,它们仍然可以被访问. 在类的内部定义中,所有以双下划线开始的名字都被“翻译”成前面加上单下划线和类名的形式. 示例: >>> class Tes

Mysql数据库大量删除操作及谈面向对象中的封装继承和多态原理(图)

Mysql数据库大量删除操作及谈面向对象中的封装继承和多态原理(图)最近进行数据库操作,遇到一个问题,就是大量删除一个数据表中的数据后,由于设定了id是自增的,导致再插入时,默认生成的id会很大,这个时候想要再次插入新的数据,应该怎么办呢?1.明确目前最后一个id的大小select id from tags order by id DESC limit 0,1; 假设返回的是9,则设置数据表从10开始自增 2.修改这个数据表从10开始自增alter table tags auto_increme