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才终止)

相关推荐
skaiuijing19 分钟前
Sparrow系列拓展篇:消息队列和互斥锁等IPC机制的设计
c语言·开发语言·算法·操作系统·arm
雯0609~2 小时前
c#:winform调用bartender实现打印(学习整理笔记)
开发语言·c#
胜天半子_王二_王半仙3 小时前
c++源码阅读__smart_ptr__正文阅读
开发语言·c++·开源
沐泽Mu3 小时前
嵌入式学习-C嘎嘎-Day08
开发语言·c++·算法
Non importa3 小时前
汉诺塔(hanio)--C语言函数递归
c语言·开发语言·算法·学习方法
LinuxST3 小时前
27、基于Firefly-rk3399中断休眠唤醒实验(按键中断)
linux·开发语言·stm32·嵌入式硬件
Tony_long74833 小时前
Python学习——猜拳小游戏
开发语言·python·学习
跳动的梦想家h3 小时前
黑马点评 秒杀下单出现的问题:服务器异常---java.lang.NullPointerException: null(已解决)
java·开发语言·redis
ac-er88884 小时前
PHP 二分法查找算法
开发语言·算法·php
陈苏同学4 小时前
机器翻译 & 数据集 (NLP基础 - 预处理 → tokenize → 词表 → 截断/填充 → 迭代器) + 代码实现 —— 笔记3.9《动手学深度学习》
人工智能·pytorch·笔记·python·深度学习·自然语言处理·机器翻译