类的继承


class Chinese:eye = 'black'def eat(self):print('吃饭,选择用筷子。')class Cantonese(Chinese):# 通过继承,Chinese类有的,Cantonese类也有pass# 验证子类可以继承父类的属性和方法,进而传递给子类创建的实例yewen = Cantonese()# 子类创建的实例,从子类那间接得到了父类的所有属性和方法print(yewen.eye)# 子类创建的实例,可调用父类的属性yewen.eat()# 子类创建的实例,可调用父类的方法
类的继承之多层继承

# 先阅读代码和注释,然后直接运行代码。class Earthman:eye_number = 2# 中国人继承了地球人class Chinese(Earthman):eye_color = 'black'# 广东人继承了中国人,同时也继承了地球人。class Cantonese(Chinese):passyewen = Cantonese()print(yewen.eye_number)print(yewen.eye_color)
类的继承之多重继承
一个类,可以同时继承多个类,语法为class A(B,C,D):。假设我们将“出生在江苏,定居在广东的人”设为一个类Yuesu,那么,它的创建语句则为class Yuesu(Yue,Su)。
class Yuesu(Yue,Su)括号里Yue和Su的顺序是有讲究的。和子类更相关的父类会放在更左侧。我认为“出生在江苏,定居在广东的人”在穿着和饮食等方面会更接近广东人,所以将 Yue 放在 Su 的左侧。
所以,广东人创建的实例在调用属性和方法时,会先在左侧的父类中找,找不到才会去右侧的父类找。(可理解为“就近原则”)
class Su:born_city = 'Jiangsu'wearing = 'thick' # 穿得较厚def diet(self):print('我们爱吃甜。')class Yue:settle_city = 'Guangdong'wearing = 'thin' # 穿得较薄def diet(self):print('我们吃得清淡。')class Yuesu(Yue,Su):passxiaoming = Yuesu()print(xiaoming.wearing)print(xiaoming.born_city)xiaoming.diet()# 答案thinJiangsu我们吃得清淡。
练习

class C0:name = 'C0'class C2(C0):num = 2class C1:num = 1class C3:name = 'C3'class C4(C1,C2,C3):passins = C4()print(ins.name) # 打印出C0print(ins.num) # 打印出1
类的定制
定制,可以新增代码
class Chinese:eye = 'black'def eat(self):print('吃饭,选择用筷子。')class Cantonese(Chinese): # 类的继承native_place = 'guangdong' # 类的定制def dialect(self): # 类的定制print('我们会讲广东话。')yewen = Cantonese()print(yewen.eye)# 父类的属性能用 blackprint(yewen.native_place)# 子类的定制属性也能用 guangdongyewen.eat()# 父类的方法能用 吃饭,选择用筷子。yewen.dialect()# 子类的定制方法也能用 我们会讲广东话
定制,也可重写代码
class Chinese:def land_area(self,area):print('我们居住的地方,陆地面积是%d万平方公里左右。'% area)class Cantonese(Chinese):# 直接对方法进行重写def land_area(self,area):print('我们居住的地方,陆地面积是%d万平方公里左右。'% int(area * 0.0188))gonger = Chinese()yewen = Cantonese()gonger.land_area(960)# 我们居住的地方,陆地面积是960万平方公里左右。yewen.land_area(960)# 我们居住的地方,陆地面积是18万平方公里左右
拓展
1、实例的对象和类之间的联系
首先,实例属性和类属性:
1)修改类属性,这会导致所有实例属性变化(因为类是模板);
2)修改实例属性,但这不会影响到其他实例,也不会影响到类。因为每个实例都是独立的个体。
其次,实例方法和类方法:
1)重写类方法,这会导致所有实例方法自动被重写;
2)实例方法不可重写
2、重写类方法”分成两个步骤
1)在类的外部写一个函数,
2)把这个新函数的名字赋值给 类.原始函数:
3、初始化函数
- 初始化函数(方法),也叫构造函数,它的意思是,当你创建一个实例的时候,这个函数就会被调用(自动执行)。
- 初始化函数的写法是固定的格式:中间是“init”,这个单词的中文意思是“初始化”,然后前后都要有【两个下划线】,然后init()的括号中,第一个参数一定要写上self,不然会报错。写成def init(self)。
- 在初始化方法内部完成类属性的创建,为类属性设置初始值,这样类中的其他方法就能直接、随时调用。不需要再调用init()


在这个类中,一旦调用,就会自动执行初始化函数创建类属性
在初始化函数的定义时,也可以设置需要传递的参数位置
4、类的继承
类的继承很大程度也是为了避免重复性劳动。比如说当我们要写一个新的类,如果新的类有许多代码都和旧类相同,又有一部分不同的时候,就可以用“继承”的方式避免重复写代码;
同理,在类的继承后,子类重写初始化函数时调用父类的初始化函数,也是因为许多代码都和旧类相同,又有一部分不同的时候,就可以用调用的方式避免重复写代码;
子类创建的实例,同时属于父类
父类创建的实例,不属于子类;
这个例子属于类的定制和调用,能够理解这个代码,其实对于类的继承最核心的知识就掌握了
在这个代码中,Knight类继承了Role类
并重新初始化函数,修改了类属性
这里可以改为另一种写法,也就是重写子类初始化函数时,调用父类的初始化函数。或者可以理解为父类方法的继承

先看这个,没有继承的类方法调用
子类继承后,修改了方法,再进行调用
