上海 day21 -- 面向对象三大特征----继承

目  录

    2w + h、抽象派生覆盖子类访问父类

    不同类之间的访问

    多继承之菱形继承、新式类和经典类、属性访问顺序

 

 前言:我们首先基于一个目的来讲继承 -- 就是代码的复用性,减少代码的冗余。

   基于这个目的我们引出两种方式—— 继承和组合。

一、继承

什么是继承?

继承是一种关系,可以理解为是‘什么是什么的关系’,在程序中就是类与类之间的关系。例如 a 类继承了b类,那么a类就可以调用b类的方法和属性。

为什么要用继承?

因为继承的一方可以直接使用被调用一方的属性和方法,其目的是重用已经有的代码,提高代码的复用性。

怎么用继承?

继承的语法:class 类名称(父类的名称):

class 类名称(父类的名称):
    类的内容 
    
#在python中 一个子类可以同时继承多个父类 

二、抽象

什么是抽象?

抽象就是将多个类之间相同的地方或有共同特征的属性抽取出来,组成一个新的共同的父类,这个过程就叫做抽象。

抽象的作用:

就是帮助我们更好的使用继承。

如何正确的使用继承呢?

1、先抽象在继承

2、继承一个现存的类,修改或扩展该类的功能

属性的查找顺序?

class A:
    text = "haha"

class B(A):
    text = "heihei"
    pass

b = B()
b.text = "xixi"

print(b.text)

对象自己的 - > 所在类中 -> 找父类 - >父类的父类 ->Object

其中Object类中最基本的类,python3 中的类都是由Object 派生出来的,这些类也称为是‘新生类’,后面会介绍!

三、派生

什么是派生?

就是原来的子类发展出于父类不同的功能就叫做‘派生’,这样的类也叫做‘派生类’。

因为对于一个子类来说会生成自己独有的功能,会与父类的代码有区别,所以这类子类统称为‘派生类’,

派生类的实质就是子类,可理解成不同的叫法。

四、覆盖

什么是覆盖?

覆盖也叫做‘重写’,overwrite。

当子类中出现与父类相同的方法或属性时,父类中的这些方法和属性会被覆盖赋值,这种现象叫做‘覆盖’。

覆盖的实质是因为属性的查找顺序决定的:先从子类自身找  ——》父类中找 ——》Object中找,

当父类中的属性和子类名字一样时,子类的属性或方法名字会覆盖父类的,就像是变量的重新赋值一样。

'''
派生与覆盖
'''
class Person:
    def say_hi(self):
        print('hello')

class Student(Person):
    def say_hi(self):
        print('hello word!')
# 覆盖:子类有和父类相同的方法名字 say_hi
s1 = Student()
s1.say_hi()  # hello word!

 

五、子类中访问父类的内容   *****(重点内容)

语法如下:

方式1:
super(当前类名称,self).你要调的父类的属性或方法
方式2:
super().你要调的父类的属性或方法
方式3:
类名称.你要调的父类的属性或方法(self)  
#方式3与继承无关 

代码示例:

class Person:
    text = 'from CQUPT'
    def say_hi(self):
        print('hello')

class Man(Person):
    def show_info(self):
        # 方式一:子类访问父类   方法:   super(子类名,self对象).父类中的方法
        print(super(Man,self).text)
        super(Man,self).say_hi()

m1 = Man()  # 对象的创建
m1.show_info() # 调用方法
方式1
class Man:
    res = '老九门串串'
    def say_some(self):
        print('欢迎光临!')

class Student(Man):
    def say_no(self):
        print('请记住下面两句话')
        # 方式2:子类访问父类  方法:  super().父类的属性或方法
        print(super().res)
        super().say_some()

stu1 = Student()  # 创建对象
stu1.say_no()  # 对象调用自身方法
方式2
class Women:
    res = '一直bb'
    def say_some(self):
        print('真烦人')

class Woman(Women):
    def say_no(self):
        # 方式3:子类访问父类   直接用父类调用父类自己的属性和方法  父类名称.方法()或父类名称.属性
        print(Women.res)
        Women.say_some(self)  # 注意:父类调用子类的方法要加 self对象,否则报错
        print('唉算了')

w1 = Woman()  #创建对象
w1.say_no()
方式3

 

强调在强调:****** (重点)

当你继承一个现有的类,并且你覆盖了父类的init方法时,必须在初始化方法的第一行调用父类的初始化方法,并传入父类所需的参数

练习:

实现一个可以限制元素类型的容器 (字典,列表,元组,集合,字符串)

"""
需求 实现一个能够限制元素类型的列表类

"""
class MyList(list):
    def __init__(self,element_type):
        super().__init__() # 调用父类的初始化方法 来完成基本的初始化
        self.element_type = element_type

    def append(self, object):
        """
        :param object: 是要存储的元素
        :return: 没有
        """
        if type(object) == self.element_type:
            #我们需要在这里访问父类的append函数来完成真正的存储操作
            super(MyList,self).append(object)
        else:
            print("sorry sir, you element type not is %s" % self.element_type)


# 创建是指定要存储的元素类型
m = MyList(int)
# 当你有需求,是需要在创建对象时 干点什么事儿  那就该想到初始化方法

m.append(1)
print(m[0])
m.append("121212")

此处知识点也可以引用为一个问题:

为什么要在初始化方法中调用父类的初始化方法?

六、组合

组合的引出?

上面提出子类访问父类中内容的方法,那么不是父子关系或者说两个类之间没有什么关联,这两个类要怎么访问(调用)对方的功能呢?

因此提出‘组合’的方法。

什么是组合?

组合也是一种关系,它描述的是两个对象之间‘什么有什么的关系’,

例如:学生有手机—用来打电话,‘学生’、‘手机’是两个不同的对象,‘学生’ 使用‘手机’打电话的功能!

因此我们可以总结说:组合,在程序中就是将一个对象作为另一个对象的属性!

代码示例:

class Phone:
    def __init__(self,price,kind,color):
        self.price = price
        self.kind = kind
        self.color = color

    def call(self):
        print("正在呼叫XXXX;")

    def send_message(self):
        print("正在发送短信....")


class Student:
    def __init__(self,name,gender,phone):
        self.name = name
        self.gender = gender
        self.phone = phone

    def show_info(self):
        print("name:%s gender:%s" % (self.name,self.gender))

phone = Phone(1000,"apple","red")

stu1 = Student("rose","male",phone)
stu1.phone.call()

组合的作用?

重用已有的代码,提高代码的复用性

如何区分何时使用继承,什么时候使用组合?

当两个类之间有相同和相似的特征时,或有‘什么是什么的关系’时,考虑用继承!

当两个类之间没有什么关联,只是普通的想要使用对方的功能时,考虑用组合!

另外:组合与继承相比耦合度更低!

七、多继承

在Python中对象明确是可以继承多个类的,即支持多继承!

菱形继承:

引入两个概念:新式类和经典类

 

 Python3 中的类都是直接或间接的继承了Objest类

新式类:显示或隐式的继承自Object类就叫做新式类,Python3 中的类都是新式类

经典类:不是Object 的子类,就是经典类。经典类只在Python2 中出现

菱形继承的查找顺序?

当出现菱形继承时,新式类 先深度,遇到有共同父类时在广度查找;

                                经典类就是深度优先,深度查找完在广度查找!

原文地址:https://www.cnblogs.com/qinsungui921112/p/11246812.html