一.类的继承
- 继承是为了代码复用和设计复用,是面向对象程序设计的重要特征之一。
- 类继承语法:
class 派生类名 (基类名): # 基类名写在括号里
派生类成员
- 在继承关系中,已有的、设计好的类称为父类或者基类。新设计的类称为子类或派生类。派生类可以继承父类的公有成员,不能继承其私有成员。
- 继承的一些特点:
1.基类的构造函数不会被自动调用,需要在其派生类的构造中亲自专门调用。
2.如果需要在派生类中调用基类的方法时,通过“基类名.方法名()"来实现,还需要带上self参数变量。
3.Python总是首先查找对应类型的方法,如果它不能在派生类(本类中)找到对应的方法,才开始到基类中逐个查找。
示例1:
class Parent: # 定义父类
parentAttr = 100
def __init__(self):
print("调用父类构造函数")
def parentMethod(self):
print("调用父类方法")
def setAttr(self, attr):
self.parentAttr = attr
def getAttr(self):
print("父类属性:", self.parentAttr)
class Child(Parent): # 定义子类
def __init__(self):
print("调用子类构造函数")
def childMethod(self):
print("调用子类方法childMethod")
child = Child() # 实例化子类
child.childMethod() # 调用子类方法
child.parentMethod() # 调用父类方法
child.setAttr(2000) # 调用父类方法
child.getAttr() # 调用父类方法
示例2:
class Person(object): # 基类必须继承于object,否则在派生类中将无法使用super()函数
def __init__(self, name='', age=18, sex='man'):
self.setName(name)
self.setAge(age)
self.setSex(sex)
def setName(self, name):
if type(name) != str: # 内置函数type()返回被测试对象的数据类型
print("姓名必须是字符串!!")
return
self.__name = name
def setAge(self, age):
if type(age) != int:
print("年龄必须是整形!!")
return
self.__age = age
def setSex(self, sex):
if sex != 'man' and sex != 'woman':
print("性别输入错误!!")
return
self.__sex = sex
def show(self):
print("姓名:", self.__name, " 年龄:", self.__age, "性别:", self.__sex)
class Student(Person): # 定义子类,并增加一个入学年份私有属性(数据成员)。
def __init__(self, name='', age=18, sex="man", year=2020):
super(Student, self).__init__(name, age, sex) # 调用基类构造方法初始化基类的私有数据成员
# Person.__init__(self,name,age,sex) 也可以这样初始化基类私有数据成员
self.setYear(year)
def setYear(self, year):
self.__year = year
def show(self):
Person.show(self) # 调用基类show()方法,基类名.方法名()
# super(Student,self).show() 也可以这样调用基类show()方法
print("入学年份:", self.__year)
if __name__ == '__main__':
Person1 = Person('John', 10, 'man')
Person1.show()
Person2 = Student('Ann', 20, 'man', 2019)
Person2.show()
Person2.setAge(99) # 调用继承的方法修改年龄
Person2.show()
二.类的多继承
- Python的类可以继承多个基类。继承的基类列表跟在类名之后。
- 语法:
class A: # 定义类A
pass
class B: # 定义类A
pass
class C(A ,B): # 定义类C继承类A和B
pass
三.方法重写
- 重写必须出现在继承中。它是指当派生类继承了基类的方法之后,如果基类方法的功能不能满足需要,需要对基类中的某些方法进行修改,可以在派生类重写基类的方法,这就是重写。
class Animal: # 定义父类
def run(self):
print("动物在跑")
class Dog(Animal): # 定义子类
def run(self):
print("狗在跑...")
dog1 = Dog() # 子类实例
dog1.run() # 子类调用重写方法
四.多态
- 在Python中,当定义一个class的时候,实际上就定义了一种数据类型。它和Python自带的数据类型(如string、list等),没什么区别。
- 在继承关系中,如果一个实例的数据类型是某个子类,那么它的数据类型也可以被看作是父类。
- 多态的好处:比如在这个例子中,我们想传入Dog、Cat……的时候,我们需要接受Animal类型久可以了,因为Dog、Cat……都是Animal类型。然后,按照Animal类型进行操作即可。由于Animal类型有run()方法。因此,传入的任意类型,只要是Animal类或子类,就会自动调用实际类型的run()方法,这就是多态的意思。
class Animal: # 定义父类
def run(self):
print("动物在跑")
class Dog(Animal): # 定义子类
def run(self):
print("狗在跑...")
def runnning(animal):
animal.run()
runnning(Animal()) # 输出动物在跑
runnning(Dog()) # 输出狗在跑...
五.运算符重载
- Python中可以通过运算符重载来实现对象之间的运算。Python把运算符与类的方法关联起来,每个运算符对应一个函数。因此重载运算符就是实现函数。
- 例如函数方法__add__,对于的重载运算符为+
示例:
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self): # 重写print方法,打印Vector对象实例信息
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self, other):
return Vector(self.a + other.a, self.b + other.b) # 重载加法运算符
vertor1 = Vector(2, 3)
vertor2 = Vector(6, 8)
print(vertor1 + vertor2) # 输出Vector (8, 11)