继承 继承 多态

python中支持单继承和多继承。在python3中,所有的类都默认继承Object类。

创建一个Hero类
class Hero:#创建一个英雄类    def __init__(self,name,level,category):#属性:名字、等级、系别        self.name=name        self.level=level        self.category=category

def run(self):        print("一个英雄要么凯旋,要么战死沙场")

def attack(self):        print("一往无前,所向披靡")

def cure(self):        print("上了战场,总要流点血")

查看Hero类的属性字典print(Hero.__dict__)

执行结果为
{‘__module__‘: ‘__main__‘, ‘__init__‘: <function Hero.__init__ at 0x00000000026D22F0>, ‘run‘: <function Hero.run at 0x00000000026D2378>, ‘attack‘: <function Hero.attack at 0x00000000026D2400>, 

‘cure‘: <function Hero.cure at 0x00000000026D2488>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Hero‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Hero‘ objects>, ‘__doc__‘: None}

创建一个法师类Master,继承Heroclass Master(Hero):#定义一个法师类    def __init__(self,name,level,category,magic_power):#属性:名字,等级,系别,法术伤害        super().__init__(name,level,category)        self.magic_power=magic_power

查看Master类的属性字典print(Master.__dict__)
执行结果为{‘__module__‘: ‘__main__‘, ‘__init__‘: <function Master.__init__ at 0x0000000002242510>, ‘__doc__‘: None}

创建一个Master类的实例#创建Master实例ZhugeLiang=Master("诸葛亮",18,"法师",1500)ZhugeLiang.run()ZhugeLiang.attack()ZhugeLiang.cure()

执行结果为:一个英雄要么凯旋,要么战死沙场一往无前,所向披靡上了战场,总要流点血

查看ZhugeLiang的属性字典
print(ZhugeLiang.__dict__)
执行结果为:{‘name‘: ‘诸葛亮‘, ‘level‘: 18, ‘category‘: ‘法师‘, ‘magic_power‘: 1500}
我们在Master类中,并没有定义run()/attack()/cure()等方法,这些方法都是在Hero类中定义的,而Master类继承了Hero类中的属性和方法。

由此,我们可以推出属性访问顺序为:实例字典————>类字典---->父类字典

思考这样一个问题,假设子类和父类中存在同名的属性和方法时,我们又该如何在子类中调用父类的方法呢?

我们在Master类中定义一个run方法:
class Master(Hero):#定义一个法师类    def __init__(self,name,level,category,magic_power):#属性:名字,等级,系别,法术伤害        super().__init__(name,level,category)        self.magic_power=magic_power

def run(self):#定义一个与父类同名的run方法
def run(self):#定义一个与父类同名的run方法    super().run()    print("哈哈哈哈,你追不上我吧,哈哈哈哈,没有办法,我就是这么强大")

ZhugeLiang=Master("诸葛亮",18,"法师",1500)ZhugeLiang.run()

执行上述代码,结果为:一个英雄要么凯旋,要么战死沙场哈哈哈哈,你追不上我吧,哈哈哈哈,没有办法,我就是这么强大

从执行结果可以看出,我们可以在子类中通过  super().父类方法  调用到父类中的方法。除此之外,我们还可以直接通过   父类名.父类方法 去调用父类中的方法
class Master(Hero):#定义一个法师类    def __init__(self,name,level,category,magic_power):#属性:名字,等级,系别,法术伤害        Hero.__init__(self,name,level,category)        self.magic_power=magic_power

def run(self):#定义一个与父类同名的run方法        Hero.run(self)        print("哈哈哈哈,你追不上我吧,哈哈哈哈,没有办法,我就是这么强大")

这段代码与上面super()方法实现的功能一致,但观察后我们发现通过super()方法调用父类方法时,方法中不用再添加self参数,但是通过父类名.父类方法的方式,必须传入一个self参数我们可以这样理解,通过super().方法名 的方法调用父类中的方法时,会自动传入一个实例对象。

python中的继承顺序我们前面说过python中支持多继承,那他们之间的继承顺序又是怎样的呢?在python中,继承的查找顺序为广度优先。class A:    def greet(self):        print("A")

class B(A):    def greet(self):        print("B")

class C(A):    def greet(self):        print("C")

class D(B):    def greet(self):        print("D")

class E(C):    def greet(self):        print("E")

class F(D,E):    def greet(self):        print("F")

me=F()me.greet()print(F.__mro__)

执行结果为F(<class ‘__main__.F‘>, <class ‘__main__.D‘>, <class ‘__main__.B‘>, <class ‘__main__.E‘>, <class ‘__main__.C‘>, <class ‘__main__.A‘>, <class ‘object‘>)


python中的多态多态是指一类事物有多种形态(多态的概念依赖与继承)

class Animal:    def eat(self):        print("天大地大,吃饭最大")

def sleep(self):        print("人生三大快事,吃饭、睡觉、打豆豆")

class Panda(Animal):    def eat(self):        print("老子可是功夫熊猫,超凶哒,我最喜欢吃小笋")

def sleep(self):        print("知道我为什么这么胖吗,因为我睡的时间长啊")

class Tiger(Animal):    def eat(self):        print("老子可不是吃素的,不然,我为什么能是百兽之王")

def sleep(self):        print("黑夜是我最好的掩护")

class Dog(Animal):    def eat(self):        print("我最喜欢吃的是骨头")

def sleep(self):        print("我一边睡觉了,一边看门")

Animal可以有多种形态,可以是Panda,可以是Tiger,也可以是Dog

多态的好处就是,当我们需要传递更多的子类,例如Cat,Pig,Bird类时,我们只需要传入一个Animal类就好了。

python中的封装封装数据的主要目的就是为了保护数据

封装其实分为两个层面:1.创建类和对象时分别会创建两者的名称空间,我们只能通过类名.属性名  或者对象.属性名的方式去访问,这本身就是一种封装。(对于这一层面的封装,类名.属性名、对象名.属性名就是访问隐藏属性的接口)2.把类中的某些属性和方法隐藏起来,定义成私有的,只在类的内部使用,外部无法访问,或者只留下少量接口提供给外部访问类的内部数据

在python中,私有属性或者方法,可以在属性、方法名前加上双下划线。也就是说,我们可以通过双下划线的方式实现隐藏属性,把属性设置成私有的。

类中所有双下划线开头的名称如__x都会自动变成:__类名__x的形式
class Demo:    __x=10    def __init__(self,name,age):        self.__name=name        self.__age=age

def __test(self):        print("just try try")

d=Demo("刘亦菲",18)print(d.__name)print(d.__age)d.__test()

执行上面代码,执行结果为:Traceback (most recent call last):  File "F:/python/stuDemo/002.py", line 11, in <module>    print(d.__name)AttributeError: ‘Demo‘ object has no attribute ‘__name‘

当我们使用下面的方式调用类的私有属性和方法时print(d._Demo__name)print(d._Demo__age)d._Demo__test()
执行结果为刘亦菲18just try try

其实我们可以这样理解,这种封装其实也就是内部帮我们改变了属性和方法的名字,将__属性名变成了__类名__属性名。这种变形的过程只是在类定义的过程中发生一次,在定义后添加属性,则不会发生凝固变形。eg:
class Demo:    __x=10    def __init__(self,name,age):        self.__name=name        self.__age=age

def __test(self):        print("just try try")

d=Demo("刘亦菲",18)Demo.__y=20print(d.__y)

执行上面的代码,运行结果为:20

这种机制也并没有从真正意义上限制我们从外部直接访问属性,知道了类名和属性名,我们依然可以通过  __类名__属性名  的方式访问到类的私有属性在继承中,父类如果不想让子类覆盖自己的方法,就需要把方法定义为私有的。

原文地址:https://www.cnblogs.com/L-C98/p/9119298.html

时间: 2024-08-04 15:54:33

继承 继承 多态的相关文章

2、C#面向对象:封装、继承、多态、String、集合、文件(上)

面向对象封装 一.面向对象概念 面向过程:面向的是完成一件事情的过程,强调的是完成这件事情的动作. 面向对象:找个对象帮你完成这件事情. 二.面向对象封装 把方法进行封装,隐藏实现细节,外部直接调用. 打包,便于管理,为了解决大型项目的维护与管理. 三.什么是类? 将相同的属性和相同方法的对象进行封装,抽象出 “类”,用来确定对象具有的属性和方法. 类.对象关系:人是类,张三是人类的对象. 类是抽象的,对象是具体的.对象可以叫做类的实例,类是不站内存的,对象才占内存. 字段是类的状态,方法是类执

Java的继承与多态

Java的继承与多态对于提高开发效率,减少开发量,是非常有帮助的,也便于代码维护.下面是根据书上讲的,我又做了改进的例子. 假设需求: 公司需要对所有人员进行管理,所有人员分为普通员工和经理人,他们的头衔.工资.生日等信息都是不一样的,但是不能开发两套系统分别进行管理,而是要一套系统完成对所有人的管理. 设计一个员工类,这是父类,定义如下: package com.myHelloWorld; import java.text.ParseException; import java.text.Si

Java 继承、多态与类的复用

摘要: 本文结合Java的类的复用对面向对象两大特征继承和多态进行了全面的介绍. 首先,我们介绍了继承的实质和意义,并探讨了继承,组合和代理在类的复用方面的异同.紧接着,我们依据继承引入了多态.介绍了它的实现机制和详细应用.此外,为了更好地理解继承和多态.我们对final关键字进行了全面的介绍. 在此基础上.我们介绍了Java中类的载入及初始化顺序.最后.我们对面向对象设计中三个十分重要的概念–重载.覆盖与隐藏进行了详细的说明. 要点: 继承 组合,继承,代理 多态 final 关键字 类载入及

JAVA基础——面向对象三大特性:封装、继承、多态

JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据.     隐藏类的实例细节,方便修改和实现. 3.封装的实现步骤 需要注意:对封装的属性不一定要通过get/set方法,其他方法也可以对封装的属性进行操作.当然最好使用get/set方法,比较标准. A.访问修饰符 从表格可以看出从上到下封装性越来越差. B.this关键字 1.this关键字代表当前

Objective-C的封装、继承与多态

面向对象有三大特征:封装.继承和多态. 一.封装 封装是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问.简而言之,信息隐藏,隐藏对象的实现细节,不让用户看到,以此来增强安全性和简化编程,进而达到封装的目的. 使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问权限来使用类的成员. 访问修饰符:private.protect.public private:私有的,不可供外部访问的信息,只有类本身能存取. prot

【转】C#三大特性之 封装、继承、多态

C#三大特性之 封装.继承.多态 一.封装: 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类).被封装的对象通常被称为抽象数据类型.  封装的意义: 封装的意义在于保护或者防止代码(数据)被我们无意中破坏.在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改. 封装提供了一个有效的途径来保护数据不被意外的破坏.相比我们将数据(用域来实现)在程序中定义为公用的(public)我们将它们(fie

Objective--C三大特性:封装,继承,多态(杂乱的东西)

OC中类的特性共有有三个,它们分别是封装.多态和继承. 1.成员变量的作用域.成员变量的作用域应该也是封装的一种,它对成员变量的作用范围做出了一些限制. @public : 在任何地方都可以直接访问成员变量. @protected:在本类和子类中可以直接访问. @private:只能在本类中访问. @package:在同一个框架内可以访问. 默认情况下在类的声明中定义的成员变量的修饰符是@protected,在类的实现中定义的成员变量的修饰符是@private. 总结:(1)封装是为了保护类中的

C++编程实践: 继承与多态

本实例及代码来自<C++ Primer Plus>(第六版) 第十三章 题目要求: 假如你是某银行首席程序员.银行要求你开发两个类,一个用于表示基本支票账户--Brass Account,另一个用于表示代表Brass Plus支票账户,它添加了透支保护的特性.也就是说,如果持有此卡的用户签出了一张超出其存款余额的支票--但是超出的数额并不是很大,银行将支付这张支票,对超出的部分收取额外的费用,并追加罚款. 下面是用于Brass Account支票账户的信息: 客户姓名 帐号 当前结余 下面是可

Objective-C 继承和多态

学习Java我们知道类有三大特征,封装,继承,多态.而在Objective-C中也有继承的概念,今天就来看看Objective-C中的继承和多态. 首先,我们来看看示例代码: //Animal.h #import <Foundation/Foundation.h> @interface Animal : NSObject { int food_consumption; //食量 int count; //数量 int parturition_days; //生产周期 } -(int)count

C++_基础_继承、多态

内容: (1)子类中的拷贝构造和拷贝赋值 (2)多继承和虚继承 (3)多态的初识 (4)虚析构的特性和使用 (5)多态的底层实现 (6)纯虚函数.抽象类的概念 1.子类中的拷贝构造和拷贝赋值 子类中的拷贝构造和拷贝赋值可能也需要显式的指定父类子对象的拷贝构造和拷贝赋值的方式 2.多继承和虚继承2.1 格式: class 子类名 : 继承方式 父类名1,继承方式 父类名2,... { //子类中的属性和行为 }; 如: 员工类 / \销售员工类 管理者类 \ / 销售管理类 叫做:钻石继承 2.2