继承与多态
今日内容
- 面向对象三大特征
- 封装
- 继承(重要)
- 多态
- 继承
- 单继承与多继承
- 继承的查询顺序
- super()和mro()列表
- 多态与多态性
内容详细
一、继承
1、什么是继承
继承是新建类的方法,新建的类被成为子类或者派生类,被继承的类被称为父类或者基类
子类可以使用父类中的属性和方法
class Base:
pass
class Son(Base):
pass
2、为什么要有继承
类用来解决对象与对象之间代码冗余的问题
继承用来解决类与类之间代码冗余的问题
3、怎么使用继承
新式类:继承了object类的子子孙孙类都是新式类
经典类:没有继承object类的子子孙孙类都是经典类
'''新式类和经典类只在python2和python3中会区分'''
二、类的继承(单继承与多继承)
1、单继承
# 父类,公共类
class People():
school = 'SH'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
# 学生类
class Student(People):
def __init__(self, name, age, gender, course=None):
if course is None:
course = []
People.__init__(self, name, age, gender)
self.courses = course
def choose_course(self, course):
self.courses.append(course)
print('%s 选课成功 %s' % (self.name, self.courses))
stu = Student('ly', 19, 'male')
# teacher类
class Teacher(People):
def __init__(self, name, age, gender, level):
self.level = level
People.__init__(self, name, age, gender)
def score(self, stu_obj, score):
stu_obj.score = score # 给学生打分
print('%s给%s打了%s分' % (self.name, stu_obj.name, score))
tea = Teacher('ly', 19, 'male', 10)
print(tea.name)
print(tea.level)
2、多继承
class A:
def test(self):
print('from A')
class B:
def test(self):
print('from B')
class C(A, B):
def info(self):
self.test()
obj = C()
obj.info() # from A
三、属性查找顺序
1、单继承下属性查找
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
#
print('Foo.f2')
self.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj = Bar() # {}
obj.f2()
# 练习
class Foo:
def __f1(self): # _Foo__f1()
print('Foo.f1')
def f2(self):
#
print('Foo.f2')
self.__f1() # _Foo__f1()
class Bar(Foo):
def __f1(self): # # _Bar__f1()
print('Bar.f1')
obj = Bar() # {}
obj.f2()
2、多继承下的属性查找
# 新式类:按照广度优先查询
# 经典类:按照深度优先查询
class A(object):
def test(self):
print('from A')
class B(A):
# def test(self):
# print('from B')
pass
class C(A):
# def test(self):
# print('from C')
pass
class D(B):
# def test(self):
# print('from D')
pass
class E(C):
# def test(self):
# print('from E')
pass
class F(D, E):
# def test(self):
# print('from F')
pass
f1 = F()
f1.test()
四、super()和mro列表
super()的使用遵循mro列表
# 在子类中调用父类中的方法
class Base:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(Base):
def __init__(self, name, age, gender, course=None):
if not course:
course = []
self.courses = course
Base.__init__(self, name, age, gender)
# 想要使用类中的方法,需要用类来调用__init__方法
def choose_course(self, course):
self.courses.append(course)
# 使用super
class Base:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(Base):
def __init__(self, name, age, gender, course=None):
if not course:
course = []
self.courses = course
# super()的使用
# super(Base, self).__init__() 旧的使用方法
super().__init__(name, age, gender)
def choose_course(self, course):
self.courses.append(course)
# 查看子类的mro列表:
stu = Student('elijah', 18, 'male')
# mro列表是调用类的方法才能查看的,对象不能调用mro方法
print(Student.mro()) # [<class '__main__.Student'>, <class '__main__.Base'>, <class 'object'>]
print(Student.__mro__)
class Parent1:
def test(self):
print('from test1')
super().info() # 调用Parent2中的info()还是Student自己的info()?
class Parent2:
def info(self):
print('from Parent2')
class Student(Parent1, Parent2):
def index(self):
self.test()
def info(self):
print('from Student')
print(Student.mro()) # [<class '__main__.Student'>, <class '__main__.Parent1'>, <class '__main__.Parent2'>, <class 'object'>]
stu = Student()
stu.index() # from test1 from Parent2
隐藏属性(方法)
class Parent:
def info(self):
print('from Parent')
def test(self):
print('from Parent')
self.info() # 调用Parent中的info()还是Student自己的info()?
class Student(Parent):
def index(self):
self.test()
def info(self):
print('from Student')
--------------------------------------
class Parent:
def __info(self): # _Parent__info
print('from Parent')
def test(self):
print('from Parent')
self.__info() # 调用Parent中的info()还是Student自己的info()?
class Student(Parent):
def index(self):
self.test()
def __info(self): # _Student__info
print('from Student')
五、多态与多态性
多态
多态通俗理解起来,就像迪迦奥特曼有三种形态一样,怎么变还是迪迦奥特曼

定义:多态指的是一类事物有多种形态
示例如下:
'''动物有多种表现形态,人也是动物之一,在这里会说话就是动物'''

多态:可以在父类中规定子类得定义哪些方法
abc模块
# 抽象类,抽象类只能被继承,不能被实例化
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self): # 该方法已经是抽象方法
pass
class People(Animal):
def speak(self):
pass
class Pig(Animal):
def speak(self):
pass
class Dog(Animal):
def speak(self):
pass
# 另一种规定方法的方法,主动报错 raise
class Animal:
def speak(self):
raise Exception:print('必须定义speak方法')
class People(Animal):
pass
class Pig(Animal):
pass
class Dog(Animal):
pass
def animal(self):
self.speak()
# 多态带来的特性
在不用考虑对象数据类型的情况下,直接调用对应的函数
无论对象是什么数据类型都可以使用同样名字的方法名
len('123')
len(123)
len([1, 2, 3])
len({'name': 'elijah'})

浙公网安备 33010602011771号