python类的继承代码_python--类的继承、多态

封装

封装是面向对象的特征之一,是对象和类概念的主要特性。

封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

继承

之前在类的实例化说到了类的公有属性和类的私有属性,其实就是类的封装,现在准备随笔的是继承,是面向对象的第二大特性。

面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程。在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

继承概念的实现方式主要有2类:实现继承、接口继承。

实现继承是指使用基类的属性和方法而无需额外编码的能力。

接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法)。

在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager也是一个人,因此这两个类都可以继承 Person类。但是 Leg类却不能继承Person类,因为腿并不是一个人。

抽象类仅定义将由子类创建的一般属性和方法,OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段

类的继承

1、继承的定义

在类名的括号中写入需要继承的类名即可

classPerson(object):deftalk(self):print("person is talking...")class BlackPerson(Person): #继承Person这个类

def walk(self): #定义子类自身的walk方法

print("BlackPerson is walking.....")

b=BlackPerson()

b.talk()#由于继承了父类的talk()方法,所以可以被调用

b.walk() #调用子类自身的walk方法

#输出

person istalking...

BlackPersonis walking.....

View Code

2、构造方法的继承

说明:因为子类有自己的属性,但是又想继承父类的属性,所以需要先继承,再重构

继承类的构造方法2种写法:

经典类写法:父类.__init(self,name,age)

新式类写法:super(子类,self).__init__(name,age)

注:建议使用新式类的写法,因为使用经典类的写法,在多继承的情况下,会出现重复调用参数的可能

classPerson(object):def __init__(self, name, age):

self.name=name

self.age=age

self.sex= "noraml"

deftalk(self):print("person is talking...")classBlackPerson(Person):def __init__(self, name, age, strength): #定义时需要传入父类的属性名

Person.__init__(self, name, age) #继承父类的构造方法,也可以写成:super(BlackPerson,self).__init__(name,age)

self.strength = strength #定义子类本身的属性

print(self.name, self.age, self.sex)defwalk(self):print("BlackPerson is walking.....")

b= BlackPerson("xiaogao", 18, "strong")#输出结果

xiaogao 18 noraml

View Code

这边不禁的有一个疑问?我不能重新写一遍,我为啥要继承父类中的方法呢?因为你重新写一遍的话,只能继承self.name和self.age,那self.sex怎么办,它也需要重写吗?所以啊,只有把父类中的构造函数全部继承过来,只能用上面这种办法?那它是怎么实现的呢?我们来画一个图:

3、子类对父类方法的重写

说明:如果我对父类中的方法不满意,我可以重写父类中的方法,当然还可以继承父类中的方法

classPerson(object):def __init__(self, name, age):

self.name=name

self.age=age

self.sex= "noraml"

deftalk(self):print("person is talking...")classBlackPerson(Person):def talk(self): #重写父类的方法

Person.talk(self) #调用父类的方法

print("BlackPerson is talking ...")defwalk(self):print("BlackPerson is walking.....")

b= BlackPerson("xiaogao", 18) #子类不写,则继承父类的构造方法

b.talk()

b.walk()#输出结果

person istalking...

BlackPersonistalking ...

BlackPersonis walking.....

View Code

其实重写不是上面说的那么简单,只需要子类的方法名和父类的中的方法名一样就算重写了,其实不然,那怎么样才算重写呢?

重写的条件:

重写方法的方法名必须和父类中被重写的方法名一模一样

重写方法的传入的参数名和参数的个数必须和父类中被重写的方法一样

我们再来看看下面的例子:

classPerson(object):deftalk(self,food):print("person is talking...{0}".format(food))classBlackPerson(Person):def talk(self): #方法名和父类的方法名一样,但是少了一个food参数

print("BlackPerson is talking ...")

b= BlackPerson("xiaogao",18,"strong")

b.talk()#输出

BlackPerson is talking ...

View Code

看着像重写了呀!其实不是重写,根据重写的条件明显两个方法的传入参数名和参数的个数都不一样,其实上面这种只是子类自己写了一个talk方法,只是名字一样,但是传入的参数和参数的个数不一样,并不是重写了父类中的方法。下面这个才是真正的重写:

classPerson(object):deftalk(self,food):print("person is talking...{0}".format(food))classBlackPerson(Person):def talk(self,food): #重写父类的方法(方法名和传入的参数名以及参数的个数与父类的方法一样)

print("BlackPerson is talking ...{0}".format(food))

b= BlackPerson("xiaogao",18,"strong")

b.talk("hotdog")#输出

BlackPerson is talking ...hotdog

View Code

类继承练习的小例子:

classSchoolMember(object):'''学校成员基类'''member= 0 #设置类属性

def __init__(self,name,age,sex):

self.name=name

self.age=age

self.sex=sex

self.enroll()#每次生成一个对象注册一次

defenroll(self):"注册"

print("just enroll a new school member [{0}]".format(self.name))

SchoolMember.member+= 1

deftell(self):print("------info:{0}-----".format(self.name))for k,v in self.__dict__.items(): #__dict__()函数是获取对象的属性,以字典的形式返回

print("\t",k,v)print("------end--------")def __del__(self):print("开除了[{0}]...".format(self.name))

SchoolMember.member-= 1

classTeacher(SchoolMember):"讲师类"

def __init__(self,name,age,sex,salary,course):

SchoolMember.__init__(self,name,age,sex)

self.salary=salary

self.course=coursedefteaching(self):"讲课方法"

print("Teacher [{0}] is teaching [{1}]".format(self.name,self.course))classStudent(SchoolMember):"学生类"

def __init__(self,name,age,sex,couser,tuition):

SchoolMember.__init__(self,name,age,sex)

self.couser=couser

self.tuition=tuition

self.amount=0defpay_tuition(self,amount):print("student [{0}] has just paied [{1}]".format(self.name,amount))

self.amount+=amount

t1= Teacher("xiaogao",18,"F*M",3000,"Python")

s1= Student("shuaigao",19,"M","PYS15",300000)

s2= Student("gaogao",12,"M","PYS15",11000)print(SchoolMember.member)del s1 #删除一个变量

t1.tell()

s2.tell()print(SchoolMember.member) #会执行__del__函数

#输出

just enroll a new school member [xiaogao]

just enroll a new school member [shuaigao]

just enroll a new school member [gaogao]3开除了[shuaigao]...------info:xiaogao-----salary3000sex F*M

course Python

name xiaogao

age18

------end--------

------info:gaogao-----couser PYS15

sex M

name gaogao

amount 0

tuition11000age12

------end--------

2开除了[gaogao]...

开除了[xiaogao]...

View Code

4、多继承

上面的都是单继承,那么什么是多继承呢?说白了,就是:子类可以继承多个父类,就叫多继承。

class SchoolMember(object): #SchoolMember类

'''学校成员基类'''

deftell(self):print("the schoolmeber is tell...")class School(object): #School类

"""学校类"""

defopen_branch(self,addr):print("openning a new branch in",addr)class Teacher(SchoolMember,School): #子类Teacher同时继承了SchoolMember,School两个类

"讲师类"

defteaching(self):"讲课方法"

print("Teacher xiaogao is teaching python")

t1=Teacher()

t1.tell()#拥有父类SchoolMember的tell方法

t1.open_branch("shanghai") #拥有父类School的open_branch方法

View Code

5、新式类

概念

新式类定义时必须继承object类,被定义继承了object类的,就叫做新式类

class Person(object): #继承object类

"新式类"

继承构造方法

新式类初始化构造方法用super关键字去继承

super(子类,self).__init__(name,age)

调用父类中相同方法或者相同属性的顺序

新式类多继承的调用方法是顺序是:广度优先查询,如下图:

代码实验如下:

①全部代码

class A(object): #新式类

def __init__(self):

self.n= "A"

classB(A):def __init__(self):

self.n= "B"

classC(A):def __init__(self):

self.n= "C"

classD(B,C):def __init__(self):

self.n= "D"d=D()print(d.n)#输出

D

View Code

先找自己本身类的属性,输出D

②注释D类中代码

classA:def __init__(self):

self.n= "A"

classB(A):def __init__(self):

self.n= "B"

classC(A):def __init__(self):

self.n= "C"

classD(B,C):passd=D()print(d.n)#输出

B

View Code

③注释B类中的代码

classA:def __init__(self):

self.n= "A"

classB(A):pass

classC(A):def __init__(self):

self.n= "C"

classD(B,C):passd=D()print(d.n)#输出

A

View Code

④注释C类中的代码

classA(object):def __init__(self):

self.n= "A"

classB(A):pass

classC(A):pass

classD(B,C):passd=D()print(d.n)#输出

A

View Code

6、经典类

概念

经典类定义,什么都不继承

class Person:

"经典类"

继承构造方法

父类.__init(self,name,age)

调用父类中相同方法或者相同属性的顺序

经典类多继承的调用方法是顺序是:深度优先查询,如下图:

代码实验如下:

①全部代码

class A:#经典类

def __init__(self):

self.n= "A"

classB(A):pass

def __init__(self):

self.n= "B"

classC(A):def __init__(self):

self.n= "C"

classD(B,C):def __init__(self):

self.n= "D"d=D()print(d.n)#输出

D

View Code

②注释D类中代码

classA:def __init__(self):

self.n= "A"

classB(A):def __init__(self):

self.n= "B"

classC(A):def __init__(self):

self.n= "C"

classD(B,C):passd=D()print(d.n)#输出

B

View Code

③注释B类中的代码

classA:def __init__(self):

self.n= "A"

classB(A):pass

classC(A):def __init__(self):

self.n= "C"

classD(B,C):passd=D()print(d.n)#输出

A

View Code

④注释A类中的代码

classA:pass

classB(A):pass

classC(A):def __init__(self):

self.n= "C"

classD(B,C):passd=D()print(d.n)#输出

C

View Code

总结:

新式类继承object类,经典类不继承任何类

新式类用super关键字继承构造方法,经典类用 父类.__init(self)来继承

新式类:广度优先查询,经典类:深度优先查询(因为新式类讲究的是新,所以要找最近的,最新的;然后经典的讲究古老,所以更远更深的)

值得注意的是,我们上面是在python2中做的,在python3中不管是经典类还是新式类,都是采用的是广度优先查询,已经废弃2中的深度查询了

多态

多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

Pyhon 很多语法都是支持多态的,比如 len(),sorted(), 你给len传字符串就返回字符串的长度,传列表就返回列表长度。

#_*_coding:utf-8_*_

classAnimal(object):def __init__(self, name): #Constructor of the class

self.name =namedef talk(self): #Abstract method, defined by convention only

raise NotImplementedError("Subclass must implement abstract method")classCat(Animal):deftalk(self):print('%s: 喵喵喵!' %self.name)classDog(Animal):deftalk(self):print('%s: 汪!汪!汪!' %self.name)def func(obj): #一个接口,多种形态

obj.talk()

c1= Cat('小晴')

d1= Dog('李磊')

func(c1)

func(d1)

View Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的封装、继承多态是面向对象编程的三个重要概念。封装是指将数据和方法封装在一个对象中,使得对象能够对外提供统一的接口,隐藏内部的实现细节。继承是指一个可以继承另一个的属性和方法,以达到代码重用的目的。多态是指一个对象可以根据上下文的不同而表现出不同的行为。 Python中的封装通过使用来实现。一个可以包含属性和方法,属性用于存储数据,方法用于处理数据。封装的好处是可以保护数据的安全性,只允许通过特定的接口来访问和修改数据。通过使用访问修饰符(如public、private和protected)可以控制属性的访问权限。 继承是通过创建一个新的继承现有的属性和方法。子默认继承的所有属性和方法,并且可以对继承进行拓展,添加新的属性和方法。继承可以提高代码的重用性和可维护性。 多态是指一个对象可以根据上下文的不同而表现出不同的行为。在Python中,多态没有明显的特殊语法,因为Python的函数的参数不必声明数据型。不同的对象可以调用相同的方法,但是根据对象的型不同,方法的实现会有所不同。这种灵活性使得代码更加可扩展和可重用。 综上所述,Python的封装、继承多态是面向对象编程中的重要概念,它们可以帮助我们更好地组织和管理代码,提高代码的可维护性和可重用性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【初学者必备】python封装继承多态笔记](https://download.csdn.net/download/qq_24067389/10476443)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Python 封装、继承多态](https://blog.csdn.net/qq_49873907/article/details/130069640)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [python面向对象:封装、继承多态](https://blog.csdn.net/weixin_44740756/article/details/117304944)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值