python语言中对象的继承含义_Python-面向对象之继承

本文详细介绍了面向对象编程中的三大核心概念:继承减少代码冗余,封装保护数据安全性,多态提高灵活性。通过实例演示Python中的继承机制、抽象与继承过程,以及新式类与经典类的区别。重点讲解了继承的实现方式、派生规则和钻石继承现象。
摘要由CSDN通过智能技术生成

面向对象阶段最重要的知识点:

面向对象的三大特性

继承(组合)

封装

多态

继承(灵魂三拷问)

什么是继承?

继承指的是定义类的方法,新定义的类称之为子类或者派生类

子类继承的类叫做父类,也叫基类/超类

继承的特性:

子类可以继承父类的属性(特征与技能)

并且可以派生出自己的属性(特征和技能)

在python中一个子类可以继承多个父类,其他语言只能继承一个父类

为什么要继承

减少代码的冗余(减少重复代码)。

如何实现继承

首先确定好谁是子类,谁是父类

在定义类时,子类(),()内写上父类名,实现继承

继承初体验:

# 父类1

class ParentClass1:

pass

# 父类2

class ParentClass2:

pass

# 子类1

class SubClass1(ParentClass1):# 继承父类1

pass

# 子类2

class SubClass2(ParentClass1,ParentClass2):# 继承父类1,父类2

pass

# 查看继承的父类:__bases__是类的属性,用来查找当前类的父类

print(SubClass1.__bases__) # (,)

print(SubClass2.__bases__) # (, )

寻找继承关系

如何寻找继承关系

要想寻找继承关系,首先要“先抽象,在继承”

抽象与继承

先抽象

抽象是一种思想

奥巴马 --> 属于人类 --> 属于动物类

哈士奇 --> 属于狗类 --> 属于动物类

把相同的属性(特征和技能)抽象出来,定义动物类,称之为父类。

动物类:

​特征:

​眼睛、鼻子、耳朵

​技能:

​吃、喝、拉、撒

再继承

继承在程序中实现

奥巴马 (对象)--> 调用人类 --> 继承动物类

哈士奇 (对象)--> 调用狗类 --> 继承动物类

继承的关系

对象是特征与技能的结合体.

类是一系列对象相同的特征与技能的结合体.

继承是一系列类相同的特征与技能的结合体.

上代码

# 父类

class OldboyPeople:

# 定义相同的属性

school = "oldboy"

def __init__(self,name,age,sex):

self.name = name

self.age = age

self.sex = sex

class OldboyTeacher(OldboyPeople):

def change_score(self):

print(f"老师{self.name} 修改分数")

class OldboyStudent(OldboyPeople):

def choose_course(self):

print(f"学生{self.name}选择课程")

stu1 = OldboyStudent("qinyj",18,"female")

tea1 = OldboyTeacher("tank",18,"female")

print(stu1.name,stu1.age,stu1.sex)

print(tea1.name,tea1.age,tea1.sex)

继承下对象属性查找顺序

在继承背景下,对象属性的查找顺序为:

对象查找属性会先从对象的名称呢过空间中查找

若对象中没有,则会去类里面查找

若当前子类里面有就返回,如果没有会去父类里面找

注意:若子类定义和父类相同的属性,会优先使用子类的。

# 验证对象属性的查找顺序:

class Foo:

def f1(self):

print("Foo.f1")

def f2(self):

print("Foo.f2")

self.f1()

class Soo(Foo):

def f1(self):

print("Soo.f1")

s = Soo()

s.f2()

# Foo.f2

# Soo.f1

# Soo-->Foo在Soo类中重新定义了f1方法,此时优先使用子类中的f1方法,这时候对象去子类的名称空间里找就会找到,打印Soo.f1

# 查看对象名称空间 __dict__

print(s.__dict__)

# __class__:查看对象的属性,查看当前对象的类

print(s.__class__) #

# 查看子类名称空间

print(s.__class__.__dict__)

# {'__module__': '__main__', 'f1': , '__doc__': None}

# 查看父类的名称空间

# __bases__:查看继承的父类

print(s.__class__.__bases__[0].__dict__)

# {'__module__': '__main__', 'f1': , 'f2': , '__dict__': , '__weakref__': , '__doc__': None}

派生

什么是派生

派生指的是子类继承父类的属性,并且派生出新的属性

子类派生出新的属性,若与父类属性相同,则调用使用子类的

继承指的是类与类的关系,子类与父类是从属的关系

子类派生新的属性并重用父类的属性

方式一:

直接调用父类的的__init__(self)方法,把__init__(self)当做普通函数使用,传入对象与继承的属性

方式二:

使用super函数,super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,通过“.” 指向父类的名称空间,将本身传入__init__(self)函数当中的一个参数

注意:两种方式不要混合使用。

class OldboyPeople:

def __init__(self,name,age,sex):

self.name = name

self.age = age

self.sex = sex

# 方式一:

# 直接调用父类的__init__(self)函数

class OldboyTeacher(OldboyPeople):

def __init__(self,name,age,sex,level):

OldboyPeople.__init__(self,name,age,sex)

self.level = level

class OldboyStudent(OldboyPeople):

def __init__(self,name,age,sex,course):

OldboyPeople.__init__(self, name, age, sex)

self.course = course

stu1 = OldboyStudent("qinyj",18,"man","python")

tea1 = OldboyTeacher("tank",18,"man","10")

print(tea1.name,tea1.level)

print(stu1.name,stu1.course)

# 方式二:

# 使用super()函数

class OldboyTeacher(OldboyPeople):

def __init__(self,name,age,sex,level):

super().__init__(name,age,sex)

self.level = level

class OldboyStudent(OldboyPeople):

def __init__(self,name,age,sex,course):

super().__init__(name, age, sex)

self.course = course

stu1 = OldboyStudent("qinyj",18,"man","python")

tea1 = OldboyTeacher("tank",18,"man","10")

print(tea1.name,tea1.level)

print(stu1.name,stu1.course)

新式类与经典类

继承了 object 类的是新式类,没有继承的是经典类

新式类:python3中都是新式类,在python3中默认继承object类

经典类:python2中凡是没有继承object类的都是经典类

mro函数

mro函数属于object类,在多继承情况下,用来查看当前类的继承顺序的

class A:

x = 2

pass

class B:

x = 3

pass

class C(A,B):

x = 1

pass

# mro函数

print(C.mro())

# [, , , ]

# 继承顺序:

# 先在自己类中找--》A--》B--》object

c = C()

print(c.x)

钻石继承(菱形继承)

在多继承的情况下形成的钻石继承

针对于新式类和经典类而言:

经典类:深度优先

新式类:广度优先

验证:

# coding=utf-8

### 新式类继承

# 继承顺序:F-D->B->E->->C->A->object-->若没有报错

class A(object):

def test(self):

print("from A")

pass

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

f = F()

f.test()

### 经典类继承

# 继承顺序:F->D->B->A->E->C-->若没有报错

class A:

# def test(self):

# print("from A")

pass

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

f = F()

f.test()

实战-通过继承实现修改json模块支持的数据类型

import json

from datetime import datetime,date

print(json.JSONEncoder)

'''

json 支持的python数据类型

+-------------------+---------------+

| Python | JSON |

+===================+===============+

| dict | object |

+-------------------+---------------+

| list, tuple | array |

+-------------------+---------------+

| str | string |

+-------------------+---------------+

| int, float | number |

+-------------------+---------------+

| True | true |

+-------------------+---------------+

| False | false |

+-------------------+---------------+

| None | null |

+-------------------+---------------+

'''

print(datetime.today())

print(date.today())

# 开发者的角度来说,我们想要把date.today() 或者datetime.today() 当成json 的value值保存为json文件

# 但json数据类型只支持字符串,那么我们可以这么做,将执行结果强转为str

dic = {

"name":"qinyj",

"today":str(date.today())

}

print(json.dumps(dic)) # {"name": "qinyj", "today": "2019-10-10"}

# 我们从源码角度来看,有可能以后会自己修改源码

class MyJson(json.JSONEncoder):

# 子类重新派生出来default功能,优先用子类的

def default(self, o):

if isinstance(o,date):

return o.strftime("%Y-%m-%d %X")

else:

# 不满足条件还是继承父类的default方法的功能

return super().default(self,o)

dic = {

"name":"qinyj",

"today":date.today()

}

# isinstance() :判断一个对象是否是一个已知的类型

print(isinstance(dic,date))

print(isinstance(dic.get("today"),date))

print(json.dumps(dic,cls=MyJson)) # 默认cls=None,默认指向的是原json的JSONEncoder

# {"name": "qinyj", "today": "2019-10-10 00:00:00"}

小结

1.什么是继承?

继承指的是新建类的方法, 新建的类称之为子类或者派生类,子类继承的类叫做父类,也称之为基类或超类.

继承的特征:

子类可以继承父类的属性(特征与技能), 并且可以派生出自己的属性(特征与技能).

2.继承的目的:

继承的目的是为了减少代码冗余(减少重复代码).

3.什么是抽象?

抽象指的是抽取相似的部分,称之为抽象.

4.继承的关系:

对象是特征与技能的结合体.

类是一系列对象相同的特征与技能的结合体.

继承是一系列类相同的特征与技能的结合体.

5.在继承背景下,对象属性的查找顺序:

1.对象查找属性会先从对象的名称空间中查找.

2.若对象没有,则会去类里面找.

3.若当前类是子类,并且没有对象找的属性,会去父类中查找

6.什么是派生?

派生指的是子类继承父类的属性,并且派生出新的属性.(*****)

子类派生出新的属性,若与父类的属性相同,则以子类的为准.

继承是谁与谁的关系, 指的是类与类的关系,子类与父类是从属关系.

7.子类派生出新的属性,并重用父类的属性:

- 直接通过 父类.(调用)__init__,把__init__当做普通函数使用,传入对象与继承的属性.

- super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,

8.什么经典类与新式类:

继承object的类都称之为新式类.

在python2中,凡是没有继承object的类都是经典类.

9.在多继承的情况下形成的钻石继承 (继承顺序)

- 经典类:

深度优先

- 新式类:

广度优先

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值