亿豪的python学习 day13

今天的学习内容

继承

语法角度讲
继承方法
1. 代码:
class 父类:
def 父类方法(self):
方法体

class 子类(父类):
def 子类方法(self):
方法体

儿子 = 子类()
儿子.子类方法()
儿子.父类方法()

2. 说明:

子类直接拥有父类的方法.
内置函数
isinstance(对象, 类型)
返回指定对象是否是某个类的对象。
issubclass(类型,类型)
返回指定类型是否属于某个类型。
继承数据
1. 代码
class 子类(父类):
def init(self,参数列表):
super().init(参数列表)
self.自身实例变量 = 参数
2. 说明
子类如果没有构造函数,将自动执行父类的,但如果有构造函数将覆盖父类的。此时必须通过super()函数调用父类的构造函数,以确保父类实例变量被正常创建。
定义
重用现有类的功能,并在此基础上进行扩展。
说明:子类直接具有父类的成员(共性),还可以扩展新功能。
优点
一种代码复用的方式。
缺点
耦合度高:父类的变化,直接影响子类。
设计角度讲
定义
将相关类的共性进行抽象,统一概念,隔离变化。
适用性
多个类在概念上是一致的,且需要进行统一的处理。
相关概念
父类(基类、超类)、子类(派生类)。
父类相对于子类更抽象,范围更宽泛;子类相对于父类更具体,范围更狭小。
单继承:父类只有一个(例如 Java,C#)。
多继承:父类有多个(例如C++,Python)。
Object类:任何类都直接或间接继承自 object 类。
多继承
一个子类继承两个或两个以上的基类,父类中的属性和方法同时被子类继承下来。
同名方法的解析顺序(MRO, Method Resolution Order):
类自身 --> 父类继承列表(由左至右)–> 再上层父类
A
/
/
B C
\ /
\ /
D

多态

设计角度讲
定义
父类的同一种动作或者行为,在不同的子类上有不同的实现。
作用
1. 在继承的基础上,体现类型的个性化(一个行为有不同的实现)。
2. 增强程序扩展性,体现开闭原则。
语法角度讲
重写
子类实现了父类中相同的方法(方法名、参数)。
在调用该方法时,实际执行的是子类的方法。
快捷键
Ctrl + O
内置可重写函数
Python中,以双下划线开头、双下划线结尾的是系统定义的成员。我们可以在自定义类中进行重写,从而改变其行为。
转换字符串
__str__函数:将对象转换为字符串(对人友好的)
__repr__函数:将对象转换为字符串(解释器可识别的)
运算符重载
定义:让自定义的类生成的对象(实例)能够使用运算符进行操作。
算数运算符

反向算数运算符重载

复合运算符重载

比较运算重载

设计原则

开-闭原则(目标、总的指导思想)
Open Closed Principle
对扩展开放,对修改关闭。
增加新功能,不改变原有代码。
类的单一职责(一个类的定义)
Single Responsibility Principle
一个类有且只有一个改变它的原因。
依赖倒置(依赖抽象)
Dependency Inversion Principle
客户端代码(调用的类)尽量依赖(使用)抽象。
抽象不应该依赖细节,细节应该依赖抽象。
组合复用原则(复用的最佳实践)
Composite Reuse Principle
如果仅仅为了代码复用优先选择组合复用,而非继承复用。
组合的耦合性相对继承低。
里氏替换(继承后的重写,指导继承的设计)
Liskov Substitution Principle
父类出现的地方可以被子类替换,在替换后依然保持原功能。
子类要拥有父类的所有功能。
子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。
迪米特法则(类与类交互的原则)
Law of Demeter
不要和陌生人说话。
类与类交互时,在满足功能要求的基础上,传递的数据量越少越好。因为这样可能降低耦合度。

注:以下为关键内容:
在这里插入图片描述
注:上图为子类调用父类构造方法的内存图,虚线框为栈幀,通过super()打点调用父类构造方法

继承 - 设计角度

老张开车去东北
需求变化:
坐飞机
坐火车
骑车…

面向对象设计原则:

  1. 开闭原则
    开放 关闭
    允许增加新功能 不能修改以前的代码
  2. 依赖倒置
    使用父,不使用子。

三大特征:
继承:抽象变化 --> 统一变化 --> 隔离变化
多态:重写父类方法 --> 传递子类对象
在这里插入图片描述
注:上图违反开闭原则指左边类在调用右边类方法时采取直接调用的方式,导致代码仍是面向过程思想。依赖倒置通过抽象提取出总的父类,不论子类怎么变化,万变不离其宗

"""
    继承 --  方法

    财产继承:钱不用孩子挣,但是可以花。
    皇位继承:江山不用孩子打,但是可以坐。
    代码继承:子类不用写,但是可以直接使用。

    抽象:从许多个事物中,舍弃个性、非本质的属性,抽出共性、本质的过程。
    练习:exercise01
"""


# 多个类,在概念上是一致的,且有相同的代码,
class Person:
    def say(self):
        print("说话")


class Student(Person):
    def study(self):
        print("学习")


class Teacher(Person):

    def teach(self):
        print("讲课")


# 子类对象,具有父类成员。
s01 = Student()
s01.say()
s01.study()

# 父类对象,不能使用子类成员。
p01 = Person()
p01.say()

# python 内置函数
# 学生对象s01 是一种 Student学生类型
print(isinstance(s01, Student))  # True
# 学生对象s01 是一种 Person人类型
print(isinstance(s01, Person))  # True
# 学生对象s01 是一种 Teacher老师类型
print(isinstance(s01, Teacher))  # False
# 人对象p01 是一种 Student学生类型
print(isinstance(p01, Student))  # False

# 学生类型 是一种 Student学生类型
print(issubclass(Student, Student))  # True
# 学生类型  是一种 Person人类型
print(issubclass(Student, Person))  # True
# Student 是一种 Teacher老师类型
print(issubclass(Student, Teacher))  # False
# Student 是一种 Student学生类型
print(issubclass(Person, Student))  # False

# 学生对象s01 是 Student学生类型
print(type(s01) == Student)  # True
# 学生对象s01 是 Person人类型
print(type(s01) == Person)  # False
# 学生对象s01 是 Teacher老师类型
print(type(s01) == Teacher)  # False
# 人对象p01 是 Student学生类型
print(type(p01) == Student)  # False
class Person:
    def __init__(self,name=""):
        self.name = name

"""
# 子类如果没有构造函数,使用父类构造函数。
class Student(Person):
    pass

s01 = Student("悟空")
print(s01.name)
"""

# 如果子类有构造函数,会覆盖父类构造函数。
# 必须调用父类构造函数
class Student(Person):
    def __init__(self, name="", score=0):
        super().__init__(name)# 调用父类构造函数
        self.score = score

# 执行的是子类构造函数
s01 = Student("悟空", 100)
print(s01.score)
print(s01.name)
class Car:
    def __init__(self,brand="", price=0.0):
        self.brand = brand
        self.price = price

    # 自定义对象 --> 字符串
    #   对人友好(没限制)
    def __str__(self):
        return "%s汽车的价格是%d"%(self.brand,self.price)

    #   对解释器友好(python语法限制)
    def __repr__(self):
        return 'Car("%s",%d)'%(self.brand,self.price)

c01 = Car("荣威",200000)
print(c01)# <__main__.Car object at 0x7fbff21977f0>
# content = c01.__str__()
# print(content)

c02 = Car("宝马",400000)
# eval : 将字符串作为python代码执行  -->  灵活
re = eval("1+2*3")
print(re)# 7

# 克隆对象 -- 相同的对象,重新开辟空间再创建一份。  【互不影响】
c03 = eval(c02.__repr__())
"""
    运算符重载
"""

class Vector1:
    def __init__(self, x=0):
        self.x = x

    def __str__(self):
        return "向量的分量是:" + str(self.x)

    # +  (习惯创建新对象)
    def __add__(self, other):
        return Vector1(self.x + other.x)

    # += (习惯在原有对象基础上进行修改)
    def __iadd__(self, other):
        self.x += other.x
        return self

    # # 定义当前类对象的比较依据
    # def __eq__(self, other):
    #     return self.x  ==  other.x

注:所有python类都有一个共同的父类object类,所有运算符本质上都是object类的方法,所以可以直接重写实现不同功能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值