python学习面向对象Day13(P137~~148)

这篇博客回顾了Python面向对象编程的第12天内容,详细讲解了继承的概念、方法、变量,以及开闭原则和多态。通过实例解析了如何使用继承来设计代码,以及多态在代码中的应用,强调了继承和多态在提高代码复用性和灵活性方面的重要性。
摘要由CSDN通过智能技术生成

b站达内python课学习笔记

P137 Python面向对象-5.1 课程回顾

一、Day12复习

"""
    复习
        View   Model  Controller
        界面    数据    业务逻辑
        变化    载体     变化
"""


class XXController:
    def add_xx(self, a):
        print("Controller 添加了数据", a)


class XXView:
    def __init__(self):
        self.c = XXController()

    def input_xx(self):
        # 需求:调用XXController类中的实例方法add_xx
        self.c.add_xx(100)


v = XXView()
v.input_xx()

P138 Python面向对象-5.2 课后作业解析

一、练习1

在class StudentManagerController类内添加排序函数:

    def order_by_score(self):
        """
            根据成绩,对self.__stu_list进行升序排列
        """
        for r in range(len(self.__stu_list) - 1):
            for c in range(r + 1, len(self.__stu_list)):
                if self.__stu_list[r].score > self.__stu_list[c].score:
                    self.__stu_list[r], self.__stu_list[c] = self.__stu_list[c], self.__stu_list[r]

在class StudentManagerView类内添加函数:

    def __output_student_by_score(self):
        self.__manager.order_by_score()
        self.__output_students(self.__manager.stu_list)

P139 Python面向对象-5.3 继承

一、继承

"""
    继承 -- 方法
        财产:钱不用孩子挣,但是可以花。
        皇位:江山不用孩子打,但是可以坐。
        代码:子类不用写,但是可以用。
"""
'''
# 多个子类在概念上一致的,所以就抽象出一个父类.
# 多个子类的共性,可以提取到父类中.
# 在实际开发过程中:
# 从设计角度讲:先有子,再有父.
# 从编码角度讲:先有父,再有子.
'''

class Person:
    def say(self):
        print("说话")


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


class Teacher(Person):
    def teach(self):
        print("讲课")

P140 Python面向对象-5.4 继承的方法

一、继承的方法和父类子类间的关系

class Person:
    def say(self):
        print("说话")


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


class Teacher(Person):
    def teach(self):
        print("讲课")

'''
继承的方法
'''
s01 = Student()
# 子类对象可以调用子类成员,也可以调用父类成员.
s01.study()
s01.say()  # 父类成员

p01 = Person()
# 父类对象只可以调用父类成员,不能调用子类成员.
p01.say()

'''
父类和子类间的关系
'''
t01 = Teacher()

# python 内置函数
# 1. 判断对象是否属于一个类型
# "老师对象" 是 一个老师类型
print(isinstance(t01, Teacher))  # True
# "老师对象" 不是 一个学生类型
print(isinstance(t01, Student))  # False
# "老师对象" 是 一个人类型
print(isinstance(t01, Person))  # True

# 2.判断一个类型是否属于另一个类型
# "老师类型" 不是 一个学生类型
print(issubclass(Teacher, Student))  # False
# "老师类型" 是 一个人类型
print(issubclass(Teacher, Person))  # True
# "人类型" 不是 一个老师类型
print(issubclass(Person, Teacher))  # False

练习

"""
    定义父类
        动物(行为:叫)

    定义子类
        狗(行为:跑)
        鸟(行为:飞)

    创建三个类型的对象
    体会:isinstance(对象,类型)
    体会:issubclass(类型,类型)
"""


class Animal:
    def shout(self):
        print("喊叫")


class Bird(Animal):
    def fly(self):
        print("飞")


class Dog(Animal):
    def run(self):
        print("跑")


animal = Animal()
bird = Bird()
dog = Dog()
print(isinstance(animal, Bird))
print(isinstance(dog, Animal))

print(issubclass(Animal, Bird))
print(issubclass(Dog, Animal))

P141 Python面向对象-5.5 继承的变量

一、继承的变量

"""
    继承 -- 变量
"""


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):
        super().__init__(name)
        self.score = score


p01 = Person("李四")
print(p01.name)

s01 = Student("张三", 100)
print(s01.score)
print(s01.name)

内存图

在这里插入图片描述

练习

"""
    定义父类
        车(数据:品牌,速度)

    定义子类
        电动车(数据:电池容量,充电功率)

    创建两个对象
    画出内存图.
"""
class Car:
    """
        车
    """
    def __init__(self,brand,speed):
        self.brand = brand
        self.speed = speed

class Electrocar(Car):
    """
        电动车
    """
    def __init__(self,brand,speed,battery_capacity,charging_power):
        super().__init__(brand,speed)
        self.battery_capacity = battery_capacity
        self.charging_power = charging_power


c01 = Car("奔驰",230)
print(c01.brand)

e01 = Electrocar("比亚迪",120,15000,220)
print(e01.brand)
print(e01.charging_power)

P142 Python面向对象-5.6 继承的设计01

一、面向对象设计原则:开-闭原则

Open Closed Principle
对扩展开放,对修改关闭。
增加新功能,不改变原有代码。

示例代码


# 需求:老张开车去东北
# 变化:    坐飞机
#          坐火车
#          骑车
#          ...
'''
# 违反了开闭原则:
#  如果增加火车,需要增加"火车类",再修改人类中的go_to方法.
'''
class Person:
    def __init__(self, name):
        self.name = name

    def go_to(self, vehicle, str_position):

        # 如果是汽车
        if type(vehicle) == Car:
            vehicle.run(str_position)
        # 否则如果是飞机
        elif type(vehicle) == Airplane:
            vehicle.flay(str_position)


class Car:
    def run(self, str_position):
        print("汽车开到", str_position)


class Airplane:
    def flay(self, str_position):
        print("飞机飞到", str_position)


p01 = Person("老张")
c01 = Car()
a01 = Airplane()
p01.go_to(c01, "东北")
p01.go_to(a01, "东北")
示意图

在这里插入图片描述

P143 Python面向对象-5.7 继承的设计,多态

一、面向对象设计原则

1、类的单一职责(一个类的定义)

Single Responsibility Principle
一个类有且只有一个改变它的原因。

2、依赖倒置(依赖抽象)

Dependency Inversion Principle
客户端代码(调用的类)尽量依赖(使用)抽象的组件。
抽象的是稳定的。实现是多变的。

二、依赖倒置原则更替上述示意图

在这里插入图片描述

三、多态

父类的同一种动作或者行为,在不同的子类上有不同的实现。

用多态改进之前的代码,使其满足开闭原则

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

class Vehicle:
    """
        交通工具,代表所有具体的交通工具(火车/飞机..)
        继承:隔离子类变化,将子类的共性(坐/飞..)提取到父类(运输)中.
    """

    def transport(self, str_position):
        # 因为父类太过于抽象,所以写不出方法体.
        pass


# 客户端代码,用交通工具。
class Person:
    def __init__(self, name):
        self.name = name

    def go_to(self, vehicle, str_position):
        # 多态:调用父,执行子.
        # 调用的是交通工具的运输方法
        # 执行的是飞机的运输方法或者汽车的运输方法
        vehicle.transport(str_position)


# -------以上是架构师完成的--以下是程序员完成的-----
class Car(Vehicle):
    def transport(self, str_position):
        print("汽车开到", str_position)


class Airplane(Vehicle):
    def transport(self, str_position):
        print("飞机飞到", str_position)


p01 = Person("老张")
c01 = Car()
a01 = Airplane()
p01.go_to(c01, "东北")
p01.go_to(a01, "东北")

P144~145 Python面向对象-5.8&5.9 习题练习01&02

一、练习1

"""
    手雷炸了,可能伤害敌人/玩家的生命.
             还可能伤害未知事物(鸭子.房子....)
    要求:增加了新事物,不影响手雷。
    体会:继承的作用
         多态的体现
         设计原则
            开闭原则
            单一职责
            依赖倒置
    画出设计图
    15:35
"""


class Granade:
    def __init__(self, atk):
        self.atk = atk

    def explode(self, damage_target):
        # 如果传入的不是子类,则报错.
        if not isinstance(damage_target, Damageable):
            raise ValueError("不是Damageable的子类")

        print("爆炸")
        # 多态:
        # 调用父类代表(玩家/敌人.....)的可以受伤者.
        # 执类行子(具体玩家/敌人.....)
        damage_target.damage(self.atk)


class Damageable:
    """
        可以受伤
        继承:统一多个子类的概念,隔离变化。
    """

    def damage(self, value):
        # 如果子类不重写,则异常。
        raise NotImplementedError()


# ------------------------------
class Player(Damageable):
    def __init__(self, hp):
        self.hp = hp

    def damage(self, value):
        self.hp -= value
        print("玩家受伤啦")
        print("碎屏")


class Enemy(Damageable):
    def __init__(self, hp):
        self.hp = hp

    def damage2(self, value):
        self.hp -= value
        print("敌人受伤喽")
        print("头顶爆字")


g01 = Granade(100)
e01 = Enemy(200)
p01 = Player(300)
g01.explode(p01)

示意图

在这里插入图片描述

P146 Python面向对象-5.10 习题练习03

一、练习1

"""
    定义图形管理器类
        1. 管理所有图形
        2. 提供计算所有图形总面积的方法

    具体图形:
        圆形(pi × r ** 2)
        矩形(长*宽)
        ...

    测试:
        创建1个圆形对象,1个矩形对象,添加到图形管理器中.
        调用图形管理器的计算面积方法,输出结果。

    要求:增加新图形,不修改图形管理器的代码.
    体会:面向对象三大特征:
            封装/继承/多态
         面向对象设计原则:
            开闭/单一/倒置

"""


class GraphicManager:
    def __init__(self):
        self.__graphics = []

    def add_graphic(self, graphic):
        if isinstance(graphic, Graphic):
            self.__graphics.append(graphic)
        else:
            raise ValueError()

    def get_total_area(self):
        total_area = 0
        # 遍历图形列表,累加每个图形的面积
        for item in self.__graphics:
            # 多态:
            # 调用的是图形
            # 执行的是圆形/矩形...
            total_area += item.calculate_area()
        return total_area

class Graphic:
    def calculate_area(self):
        # 如果子类不重写,则异常.
        raise NotImplementedError()
#-----------------------------------
class Circle(Graphic):
    def __init__(self,radius):
        self.radius = radius

    def calculate_area(self):
        return 3.14 * self.radius **2


class Rectanlge(Graphic):
    def __init__(self,length,width):
        self.lenght = length
        self.width = width


    def calculate_area(self):
        return self.lenght *  self.width


c01 = Circle(5)
r01 = Rectanlge(10,20)
manager = GraphicManager()
manager.add_graphic(c01)
manager.add_graphic(r01)
re = manager.get_total_area()
print(re)

示意图

在这里插入图片描述

P147 Python面向对象-5.11 类与类的关系

一、类与类的关系

泛化

子类与父类的关系,概念的复用,耦合度最高;
B类泛化A类,意味B类是A类的一种;
做法:B类继承A类

关联(聚合/组合)

部分与整体的关系,功能的复用,变化影响一个类;
A与B关联,意味着B是A的一部分;
做法:在A类中包含B类型成员。

依赖

合作关系,一种相对松散的协作,变化影响一个方法;
A类依赖B类,意味A类的某些功能靠B类实现;
做法:B类型作为A类中方法的参数,并不是A的成员。

二、设计原则:组合复用原则(复用的最佳实践)

Composite Reuse Principle
如果仅仅为了代码复用优先选择组合复用,而非继承复用。
组合的耦合性相对继承低。

举例示意图

在这里插入图片描述

P148 Python面向对象-5.12 作业及总结

一、继承

语法

  1. 代码
    class 子类(父类):
    def init(self,参数列表):
    super().init(参数列表)
    self.自身实例变量 = 参数
  2. 说明
    – 子类拥有父类的所有成员。
    – 子类如果没有构造函数,将自动执行父类的,但如果有构造函数将覆盖父类的。此时必须通过super()函数调用父类的构造函数,以确保父类属性被正常创建。

定义

  1. 重用现有类的功能与概念,并在此基础上进行扩展。
  2. 说明:
    – 子类直接具有父类的成员(共性),还可以扩展新功能。
    – 事物具有一定的层次、渊源,继承可以统一概念。
    例如:公司组织架构
    老板
    行政中心 营销中心 技术中心
    人力资源 行政部 销售部 策划部 研发部 产品部

优点

  1. 一种代码复用的方式。
  2. 以层次化的方式管理类。

缺点

耦合度高

作用

隔离客户端代码与功能的实现方式。

适用性

多个类在概念上是一致的,且需要进行统一的处理。

二、多态

定义

父类的同一种动作或者行为,在不同的子类上有不同的实现。

作用

  1. 继承将相关概念的共性进行抽象,多态在共性的基础上,体现类型的个性化(一个行为有不同的实现)。
  2. 增强程序扩展性,体现开闭原则。

重写

子类实现了父类中相同的方法(方法名、参数),在调用该方法时,实际调用的是子类的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值