Python---继承

1、什么是继承

我们接下来来聊聊Python代码中的"继承":类是用来描述现实世界中同一组事务的共有特性的抽象模型,但是类也有上下级和范围之分,比如:生物 => 动物 => 哺乳动物 => 灵长型动物 => 人类 => 黄种人

从哲学上说,就是共性与个性之间的关系,比如:白马和马!所以,我们在OOP代码中,也一样要体现出类与类之间的共性与个性关系,这里就需要通过类的继承来体现。简单来说,如果一个类A使用了另一个类B的成员(属性和方法),我们就可以说A类继承了B类,同时这也体现了OOP中代码重用的特性!

2、继承的基本语法

假设A类要继承B类中的所有属性和方法(私有属性和私有方法除外)


class B(object):

pass

clss A(B):

pass

a = A()

a.B中的所有公共属性

a.B中的所有公共方法


案例:Person类与Teacher、Student类之间的继承关系


class Person(object):

def eat(self):

print('i can eat food!')

def speak(self):

print('i can speak!')

class Teacher(Person):

pass

class Student(Person):

pass

teacher = Teacher()

teacher.eat()

teacher.speak()

student = Student()

student.eat()

studnet.speak()


3、与继承相关的几个概念

继承:一个类从另一个已有的类获得其成员的相关特性,就叫作继承!

派生:从一个已有的类产生一个新的类,称为派生!

很显然,继承和派生其实就是从不同的方向来描述的相同的概念而已,本质上是一样的!

父类:也叫作基类,就是指已有被继承的类!

子类:也叫作派生类或扩展类

扩展:在子类中增加一些自己特有的特性,就叫作扩展,没有扩展,继承也就没有意义了!

单继承:一个类只能继承自一个其他的类,不能继承多个类,单继承也是大多数面向对象语言的特性!

多继承:一个类同时继承了多个父类, (C++、Python等语言都支持多继承)

4、单继承

单继承:一个类只能继承自一个其他的类,不能继承多个类。这个类会有具有父类的属性和方法。

基本语法:


1、定义一个共性类(父类)

class Person(object):

pass

2、定义一个个性类(子类)

class Teacher(Person):

pass


案例:比如汽车可以分为两种类型(汽油车、电动车)


1、定义一个共性类(车类)

class Car(object):

def run(self):

print('i can run')

2、定义汽油车

class GasolineCar(Car):

pass

3、定义电动车

class EletricCar(Car):

pass

bwm = GasolineCar()

bwm.run()


5、单继承特性:传递性

在Python继承中,如A类继承了B类,B类又继承了C类。则根据继承的传递性,则A类也会自动继承C类中所有属性和方法(公共)


class C(object):

def func(self):

print('我是C类中的相关方法func')

class B(C):

pass

class A(B):

pass

a = A()

a.func()


6、编写面向对象代码中的常见问题

答:在Python中,类理论上是不区分大小写的。但是要遵循一定的命名规范:首字母必须是字母或下划线,其中可以包含字母、数字和下划线,而且要求其命名方式采用大驼峰。

电动汽车:EletricCar

父类:Father

子类:Son

问题2:父类一定要继承object么?Car(object)

答:在Python面向对象代码中,建议在编写父类时,让其自动继承object类。但是其实不写也可以,因为默认情况下,Python中的所有类都继承自object。

问题3:打印属性和方法时,都喜欢用print


class Person():

def init(self, name):

self.name = name

def speak(self):

print('i can speak')

创建对象,打印属性和方法

p = Person('Tom')

print(p.name)

p.speak()


7、多继承

什么是多继承?

Python语言是少数支持多继承的一门编程语言,所谓的多继承就是允许一个类同时继承自多个类的特性。

基本语法:


class B(object):

pass

class C(object):

pass

class A(B, C):

pass

a = A()

a.B中的所有属性和方法

a.C中的所有属性和方法


案例:汽油车、电动车 => 混合动力汽车(汽车 + 电动)


class GasolineCar(object):

def run_with_gasoline(self):

print('i can run with gasoline')

class EletricCar(object):

def run_with_eletric(self):

print('i can run with eletric')

class HybridCar(GasolineCar, EletricCar):

pass

tesla = HybridCar()

tesla.run_with_gasoline()

tesla.run_with_eletric()


注意:虽然多继承允许我们同时继承自多个类,但是实际开发中,应尽量避免使用多继承,因为如果两个类中出现了相同的属性和方法就会产生命名冲突。

8、子类扩展:重写父类属性和方法

扩展特性:继承让子类继承父类的所有公共属性和方法,但是如果仅仅是为了继承公共属性和方法,继承就没有实际的意义了,应该是在继承以后,子类应该有一些自己的属性和方法。

什么是重写?

重写也叫作覆盖,就是当子类成员与父类成员名字相同的时候,从父类继承下来的成员会重新定义!

此时,通过子类实例化出来的对象访问相关成员的时候,真正其作用的是子类中定义的成员!

上面单继承例子中 Animal 的子类 Cat和Dog 继承了父类的属性和方法,但是我们狗类Dog 有自己的叫声'汪汪叫',猫类 Cat 有自己的叫声 '喵喵叫' ,这时我们需要对父类的 call() 方法进行重构。如下:


class Animal(object):

def eat(self):

print('i can eat')

def call(self):

print('i can call')

class Dog(Animal):

pass

class Cat(Animal):

pass

wangcai = Dog()

wangcai.eat()

wangcai.call()

miaomiao = Cat()

miaomiao.eat()

miaomiao.call()


Dog、Cat子类重写父类Animal中的call方法:


class Animal(object):

def eat(self):

print('i can eat')

公共方法

def call(self):

print('i can call')

class Dog(Animal):

重写父类的call方法

def call(self):

print('i can wang wang wang')

class Cat(Animal):

重写父类的call方法

def call(self):

print('i can miao miao miao')

wangcai = Dog()

wangcai.eat()

wangcai.call()

miaomiao = Cat()

miaomiao.eat()

miaomiao.call()


思考:重写父类中的call方法以后,此时父类中的call方法还在不在?

答:还在,只不过是在其子类中找不到了。类方法的调用顺序,当我们在子类中重构父类的方法后,Cat子类的实例先会在自己的类 Cat 中查找该方法,当找不到该方法时才会去父类 Animal 中查找对应的方法。

9、super()调用父类属性和方法

super():调用父类属性或方法,完整写法:super(当前类名, self).属性或方法(),在Python3以后版本中,调用父类的属性和方法我们只需要使用super().属性或super().方法名()就可以完成调用了。

案例:Car汽车类、GasolineCar汽油车、ElectricCar电动车


class Car(object):

def init(self, brand, model, color):

self.brand = brand

self.model = model

self.color = color

def run(self):

print('i can run')

class GasolineCar(Car):

def init(self, brand, model, color):

super().init(brand, model, color)

def run(self):

print('i can run with gasoline')

class ElectricCar(Car):

def init(self, brand, model, color):

super().init(brand, model, color)

电池属性

self.battery = 70

def run(self):

print(f'i can run with electric,remain:{self.battery}')

bwm = GasolineCar('宝马', 'X5', '白色')

bwm.run()

tesla = ElectricCar('特斯拉', 'Model S', '红色')

tesla.run()


10、MRO属性或MRO方法:方法解析顺序

MRO(Method Resolution Order):方法解析顺序,我们可以通过类名.__mro__类名.mro()获得"类的层次结构",方法解析顺序也是按照这个"类的层次结构"寻找到。


class Car(object):

def init(self, brand, model, color):

self.brand = brand

self.model = model

self.color = color

def run(self):

print('i can run')

class GasolineCar(Car):

def init(self, brand, model, color):

super().init(brand, model, color)

def run(self):

print('i can run with gasoline')

class ElectricCar(Car):

def init(self, brand, model, color):

super().init(brand, model, color)

电池属性

self.battery = 70

def run(self):

print(f'i can run with electric,remain:{self.battery}')

print(ElectricCar.mro)

print(ElectricCar.mro())


说明:有MRO方法解析顺序可知,在类的继承中,当某个类创建了一个对象时,调用属性或方法,首先在自身类中去寻找,如找到,则直接使用,停止后续的查找。如果未找到,继续向上一级继承的类中去寻找,如找到,则直接使用,没有找到则继续向上寻找...直到object类,这就是Python类继承中,其方法解析顺序。

综上:object类还是所有类的基类(因为这个查找关系到object才终止)

相关推荐
databook7 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar8 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780519 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_9 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机15 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机16 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机16 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机16 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i16 小时前
drf初步梳理
python·django
每日AI新事件17 小时前
python的异步函数
python