Python3 & 类的继承
Python 是一门面向对象的语言。以下简单介绍面向对象相关概念:
类:描述具有相同属性和方法的集合。简单来说就是一个模板,通它来创建对象。
对象:类的实例。
方法:类中定义的函数。
类变量:定义在类中且在函数之外的变量,在所有实例化对象中公用。
局部变量:方法中定义的变量,只作用于当前实例。
面向对象三大特性:封装、继承、多态。其中继承可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程。一个子类可以继承多个基类。
继承概念的实现方式主要有2类:实现继承、接口继承。
实现继承是指使用基类的属性和方法而无需额外编码的能力。
接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法)。
在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。
例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。
继承语法格式为:
class 基类(子类1, 子类2 ...):
...
注意:
1)当⼀个类有多个⽗类的时候,默认使⽤第⼀个⽗类的同名属性和⽅法。
2)⼦类和⽗类具有同名属性和⽅法,默认使⽤⼦类的同名属性和⽅法。
3)使⽤super() 可以⾃动查找⽗类。调⽤顺序遵循 mro 类属性的顺序。⽐较适合单继承使⽤。
继承构造函数,同时子类中定义自己的属性继承类的构造方法:
1).经典类的写法: 父类名称.init(self,参数1,参数2,...)
例如:
class Master():
def __init__(self):
self.formula = '[grandos格兰特·速溶黑咖啡]'
def make_coffee(self):
print(f"Master运用{self.formula}的配方煮咖啡~")
class Cafe():
def __init__(self):
self.formula = '[UCC·无糖速溶纯黑咖啡]'
def make_coffee(self):
print(f"Cafe运用{self.formula}的配方煮咖啡~")
class Apprentice(Cafe,Master):
def __init__(self):
self.formula = '[雀巢·北海道牧场宇治抹茶拿铁]'
def make_coffee(self):
print(f"Apprentice运用{self.formula}的配方煮咖啡~~~~")
def make_master_coffee(self):
Master.__init__(self) # self调用Master的__init__方法 (self指向Apprentice)
Master.make_coffee(self) # self调用Master的make_coffee方法(self指向Apprentice)
def make_cafe_coffee(self):
Cafe.__init__(self)
Cafe.make_coffee(self)
app = Apprentice()
app.make_coffee() #调用子类自己的make_coffee方法
app.make_master_coffee() #调用父类Master的make_coffee方法
app.make_cafe_coffee() #调用父类Cafe的make_coffee方法
输出结果:
Apprentice运用[雀巢·北海道牧场宇治抹茶拿铁]的配方煮咖啡~~~~
Master运用[grandos格兰特·速溶黑咖啡]的配方煮咖啡~
Cafe运用[UCC·无糖速溶纯黑咖啡]的配方煮咖啡~
2).新式类的写法:super(子类,self).init(参数1,参数2,....)
例如:
class Master():
def __init__(self):
self.formula = '[grandos格兰特·速溶黑咖啡]'
def make_coffee(self):
print(f"Master运用{self.formula}的配方煮咖啡~")
class Cafe():
def __init__(self):
self.formula = '[UCC·无糖速溶纯黑咖啡]'
def make_coffee(self):
print(f"Cafe运用{self.formula}的配方煮咖啡~")
class Apprentice(Master,Cafe):
def __init__(self):
self.formula = '[雀巢·北海道牧场宇治抹茶拿铁]'
def make_coffee(self):
print(f"Apprentice运用{self.formula}的配方煮咖啡~~~~")
def make_father_coffee(self):
super(Apprentice,self).__init__()
super(Apprentice,self).make_coffee()
app = Apprentice()
app.make_coffee() #调用子类自己的make_coffee方法
app.make_father_coffee() #当⼀个类有多个⽗类的时候,默认使⽤第⼀个⽗类的同名属性和⽅法。
输出结果:
Apprentice运用[雀巢·北海道牧场宇治抹茶拿铁]的配方煮咖啡~~~~
Master运用[grandos格兰特·速溶黑咖啡]的配方煮咖啡~
3).新式类的写法:super().init(参数1,参数2,....)
例如:
class Master():
def __init__(self):
self.formula = '[grandos格兰特·速溶黑咖啡]'
def make_coffee(self):
print(f"Master运用{self.formula}的配方煮咖啡~")
class Cafe(Master):
def __init__(self):
self.formula = '[UCC·无糖速溶纯黑咖啡]'
def make_coffee(self):
print(f"Cafe运用{self.formula}的配方煮咖啡~")
super().__init__()
super().make_coffee()
class Apprentice(Cafe):
def __init__(self):
self.formula = '[雀巢·北海道牧场宇治抹茶拿铁]'
def make_coffee(self):
print(f"Apprentice运用{self.formula}的配方煮咖啡~~~~")
def make_father_coffee(self):
super().__init__()
super().make_coffee()
app = Apprentice()
app.make_coffee() #调用子类自己的make_coffee方法
app.make_father_coffee()#调用父类自己的make_coffee方法
输出结果:
Apprentice运用[雀巢·北海道牧场宇治抹茶拿铁]的配方煮咖啡~~~~
Cafe运用[UCC·无糖速溶纯黑咖啡]的配方煮咖啡~
Master运用[grandos格兰特·速溶黑咖啡]的配方煮咖啡~
在Python中,可以为实例属性和⽅法设置私有权限,即设置某个实例属性或实例⽅法不继承给⼦类。
设置私有权限的⽅法:在属性名和⽅法名 前⾯ 加上两个下划线 __。
获取和修改私有属性值,⼀般定义函数名 get_xx ⽤来获取私有属性,定义 set_xx ⽤来修改私有属性值。
class Master():
def __init__(self):
self.formula = '[grandos格兰特·速溶黑咖啡]'
def make_coffee(self):
print(f"Master运用{self.formula}的配方煮咖啡~")
class Cafe(Master):
def __init__(self):
self.formula = '[UCC·无糖速溶纯黑咖啡]'
def make_coffee(self):
print(f"Cafe运用{self.formula}的配方煮咖啡~")
super().__init__()
super().make_coffee()
class Apprentice(Cafe):
def __init__(self):
self.formula = '[雀巢·北海道牧场宇治抹茶拿铁]'
self.__money = 2000000
# 定义函数:获取私有属性值 get_xx
def get_money(self):
return self.__money
# 定义函数:修改私有属性值 set_xx
def set_money(self,money):
self.__money = money
# 定义私有⽅法
def __print_info(self):
print(f"{self.formula}----{self.__money}")
def make_coffee(self):
print(f"Apprentice运用{self.formula}的配方煮咖啡~~~~")
def make_father_coffee(self):
super().__init__()
super().make_coffee()
class Tusun(Apprentice):
pass
ts = Tusun()
print(ts.get_money())
ts.set_money(3000000)
print(ts.get_money())
# ⼦类⽆法继承⽗类的私有属性和私有⽅法
#ts.__print_info() #调用父类私有方法报错
输出结果:
2000000
3000000
如果对基类/父类的方法需要修改,可以在子类中重构该方法。
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
self.weight = 'weight'
def talk(self):
print('person is talking.....')
class Chinese(Person):
def __init__(self,name,age,language):
super(Chinese,self).__init__(name,age)
self.language = language
def talk(self):
print(f'chinese person {self.name} age is {self.age} is talking.... with {self.language}')
p = Chinese('aaaa',33,'中文')
p.talk()
输出结果:
chinese person aaaa age is 33 is talking.... with 中文
类的继承的实例:
class SchoolMember(object):
member = 0
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
self.enroll()
def enroll(self):
print(f' just enrolled a new school member {self.name} ,age is {self.age} ,sex is {self.sex}')
SchoolMember.member +=1
print(f' now enrolled person number is {SchoolMember.member}')
def tell(self):
print(f' ----------- name is {self.name} -----------')
for k,v in self.__dict__.items():
print(k,v)
print('----------- end ------------')
def __del__(self):
print(f'开除了学生 {self.name}')
SchoolMember.member -=1
class Teacher(SchoolMember):
def __init__(self,name,age,sex,salary,course):
super(Teacher,self).__init__(name,age,sex)
self.salary = salary
self.course = course
def teaching(self):
print(f'teacher {self.name} ,age is {self.age} ,sex is {self.sex},salary is {self.salary} is teaching {self.course}')
class Student(SchoolMember):
def __init__(self,name,age,sex,course,tuition):
super(Student,self).__init__(name,age,sex)
self.course = course
self.tution = tuition
self.amount = 0
def pay_tuition(self,amount):
print(f'student {self.name},age is {self.age} ,sex is {self.sex},course is {self.course} has just paied {self.amount}')
print(f' ----------- the student info is -----------')
for k, v in self.__dict__.items():
print(k, v)
self.amount += amount
t1 = Teacher('胡军','38','男',9000,'数学')
t1.tell()
t1.teaching()
s1 = Student('小孙',22,'女','数学',1000)
s1.pay_tuition(500)
s1.pay_tuition(500)
输出结果:
just enrolled a new school member 胡军 ,age is 38 ,sex is 男
now enrolled person number is 1
----------- name is 胡军 -----------
name 胡军
age 38
sex 男
salary 9000
course 数学
----------- end ------------
teacher 胡军 ,age is 38 ,sex is 男,salary is 9000 is teaching 数学
just enrolled a new school member 小孙 ,age is 22 ,sex is 女
now enrolled person number is 2
student 小孙,age is 22 ,sex is 女,course is 数学 has just paied 0
----------- the student info is -----------
name 小孙
age 22
sex 女
course 数学
tution 1000
amount 0
student 小孙,age is 22 ,sex is 女,course is 数学 has just paied 500
----------- the student info is -----------
name 小孙
age 22
sex 女
course 数学
tution 1000
amount 500
开除了学生 胡军
开除了学生 小孙