面向对象之继承

Posted xp1315458571

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象之继承相关的知识,希望对你有一定的参考价值。

一、 继承

面向对象编程OOP的三大特征(封装,继承,多态)之一

1.什么是继承

在程序中,继承描述的是类和类之间的关系  例如a继承了b, a就能直接使用b已经存在的方法和属性

                     a为子类,b为父类或基类

父类  =  基类  = 超类,

子类  =  派生类

当一个子类中出现了与父类中不同的内容时,这个子类就称之为派生类

通常子类都会写一些新的代码,不可能和父类完全一样 , 即通常都是派生类,

所以派生类指的就是子类

2.为什么用:   

        为了重用已经有的代码,提高重用性

        继承的一方可以直接使用被继承一方已经有的东西

3.继承语法

class Base:
    desc = "这是一个基类"
    def show_info(self):
        print(self.desc)
    def make_money(self):
        print("一天赚一个亿...")

class SubClass(Base): #定义子类指定父类为Base
    pass
obj = SubClass() #创建子类的对象

obj.make_money( ) #一天赚一个亿...  即使子类中什么都没有也可以使用父类中已有的内容
print(obj.desc)  #这是一个基类

4. python中类的继承分为:单继承和多继承

class ParentClass1: #定义父类
    pass

class ParentClass2: #定义父类
    pass

class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
    pass

class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass
#查看继承
#__base__ 只查看从左到右继承的第一个父类
#__bases__   查看所有继承的父类
print(SubClass2.__base__)  #<class ‘__main__.ParentClass1‘>   
print(SubClass2.__bases__) #(<class ‘__main__.ParentClass1‘>, <class ‘__main__.ParentClass2‘>)

 

5.继承的步骤   先抽象再继承

抽象:  将多个子类中相同的部分,进行抽取,形成一个新的类也就是父类

    继承描述的是子类与父类之间的关系,是一种什么是什么的关系。要找出这种关系,必须先抽象出父类再在继承父类基础上扩展或修改原始功能

 

6.属性的查找顺序

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

补充:菱形继承

前提是python支持多继承

当出现了菱形继承时,新式类,先深度,当遇到了共同父类时就广度

新式类,就是深度优先 

查找顺序
技术图片

 

补充:新式类与经典类

python3中任何类都是直接或间接继承了Object

新式类,任何显式或隐式地继承自object的类就称之为新式类, python3中全都是新式类

经典类,既不是Object的子类 ,仅在python2中出现

 7.覆盖

也称之为重写 overrides

当子类出现了与父类名称完全一致的属性或是方法 会覆盖父类

 

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

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

    def append(self, object):
        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])  #1
m.append("121212")  #sorry sir, you element type not is <class ‘int‘>

二、子类中访问父类的内容

方式1:
super(当前类名称,self).你要调的父类的属性或方法


方式2:
super().你要调的父类的属性或方法


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

 

class Parent:
    text = "abc"
    def say_something(self):
        print("anything")
class Sub(Parent):
    def show_info(self):
        #访问方式一  python2和3中兼容 但是麻烦
        print(super(Sub,self).text)  #abc  访问父类属性
        super(Sub,self).say_something()  #anything  访问父类方法

        # 访问方式2  py3的新语法 最常用的方式
        print(super().text)
 super().say_something()

#方式3 直接指定类名调用 这种方法指名道姓与继承没有毛线关系
        print(Parent.text)
        Parent.say_something(self)
sub = Sub()
sub.show_info()

强调在强调  :

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

class Person:
    def __init__(self,name,gender,age,*args):
        self.name = name
        self.gender = gender
        self.age = age
        self.aa()
    def aa(self):
        print("aa run")
    def say_hi(self):
        print("name:%s ,gender:%s,age:%s" % (self.name,self.gender,self.age))

class Student(Person):
    def __init__(self,name,gender,age,number):
        super().__init__(name,gender,age)  #子类覆盖了父类的init,必需要用super调用一下完成父类初始化,不然属性不能传入父类,父类中aa不会运行验证了没有初始化
        self.number= number  #super需要在这一句之前,因为父类初始化过程中可能会有什么变化

    def say_hi(self):
        super().say_hi() #调用父类,输出语句
        print("numnber:%s" % self.number)  #这个是子类不同于父类的属性,调用父类有的属性后,自己输出一句来完善全部属性

stu = Student("rose","mael",20,"old01")
stu.say_hi()

三、组合

什么是:    也是一种关系,描述两个对象之间 是什么有什么的关系

        将一个对象作为另一个对象的属性,(实现既有什么属性又有什么属性)

        例如,学生有手机 ,学生想用手机但是又不能把手机当父类

使用目的 :     也是为了重用现有代码

应用场景:

        什么时候使用继承:  分析两个类的关系, 反应什么是什么的关系

        什么时候使用组合:  两个类之间 没有太大的关系,完全不属于同类

        优点:  另外组合相比继承,耦合度更低了 (也就是说一个代码改变另一个几乎不受影响)

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("正在发送短信....")

phone = Phone(1000,"apple","red") #实例化了Phone类的对象,也可以放在下面,只要在定义类之后就可以

class Student:
    def __init__(self,name,gender,phone): #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面向对象编程之继承与多态详解

Java面向对象之继承

JAVA面向对象之继承

Python面向对象之继承

18.Python面向对象之:继承