继承与多态

今日内容

  • 面向对象三大特征
    • 封装
    • 继承(重要)
    • 多态
  • 继承
  • 单继承与多继承
  • 继承的查询顺序
  • 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')

五、多态与多态性

多态

多态通俗理解起来,就像迪迦奥特曼有三种形态一样,怎么变还是迪迦奥特曼

image

定义:多态指的是一类事物有多种形态
示例如下:

'''动物有多种表现形态,人也是动物之一,在这里会说话就是动物'''

image

多态:可以在父类中规定子类得定义哪些方法

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'})
posted @ 2021-12-06 18:34  elijah_li  阅读(54)  评论(0)    收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中