面向对象 Object Oriented
[toc]

面向对象 Object Oriented

概述:

图说面向对象
面向对象概述

面向过程

  1. 思路:分析出解决问题的步骤,然后逐步解决 例如:婚礼筹办 — 发请柬(选照片、措词、制作) — 宴席(场地、找厨师、准备桌椅餐具、计划菜品、购买食材) — 婚礼仪式(定婚礼仪式流程、请主持人)
  2. 公式:程序 = 算法 + 数据结构
  3. 优点:所有环节、细节自己掌控。
  4. 缺点:考虑所有细节,工作量大。

面向对象

  1. 思路:找出解决问题的人,然后分配职责。 例如:婚礼筹办 — 发请柬:找摄影公司(拍照片、制作请柬) — 宴席:找酒店(告诉对方标准、数量、挑选菜品) — 婚礼仪式:找婚庆公司(对方提供司仪、制定流程、提供设备、帮助执行)
  2. 公式:程序 = 对象 + 交互
  3. 优点 (1) 思想层面:
    • 更接近于人的思维方式。
    • 有利于梳理归纳、分析解决问题。
    (2) 技术层面:
    • 高复用:对重复的代码进行封装,提高开发效率。
    • 高扩展:增加新的功能,不修改以前的代码。
    • 高维护:代码可读性好,逻辑清晰,结构规整。

类和对象

类与对象对比

  1. 类:一个抽象的概念,即生活中的”类别”。
  2. 对象:类的具体实例,即归属于某个类别的”个体”。
  3. 类是创建对象的”模板”。
    • 数据成员:名词类型的状态。
    • 方法成员:动词类型的行为。
  4. 类与类行为不同,对象与对象数据不同。 例如:(1)学生student是一个类,具有姓名,年龄等数据; 具有学习study,工作work等行为。 对象:悟空同学,28岁。 八戒同学,29岁。(2)车 car是一个类,具有类型type,速度speed等数据; 启动start,停止stop,行驶run等行为。 对象:宝马,180. 比亚迪,100.(3)狗dog是一个类,具有类型,姓名,重量weight等数据, 拉臭臭shit,玩play等行为。 对象:拉布拉多,米咻。 金毛,赵金多。(4)字符串str是一个类,”abc”是一个对象。

语法

定义类

class 类名:
    “””文档说明”””
    def _init_(self,参数列表):
        self.实例变量 = 参数
方法成员

说明: – 类名所有单词首字母大写. – init 也叫构造函数,创建对象时被调用,也可以省略。 – self 变量绑定的是被创建的对象,名称可以随意。

创建对象(实例化)

变量 = 构造函数 (参数列表)

实例成员

实例变量

  1. 语法 (1) 定义:对象.变量名 (2) 调用:对象.变量名
  2. 说明

– 首次通过对象赋值为创建,再次赋值为修改.

w01 = Wife()
w01.name = “丽丽”
w01.name = “莉莉”
  • 通常在构造函数(init)中创建。
w01 = Wife(“丽丽”,24)
print(w01.name)
  • 每个对象存储一份,通过对象地址访问。
  1. 作用:描述所有对象的共有数据。
  2. __dict__:对象的属性,用于存储自身实例变量的字典。

实例方法

  1. 语法

– 定义:

def 方法名称(self, 参数列表):
   方法体
  • 调用:
对象地址.实例方法名(参数列表)
          不建议通过类名访问实例方法
  1. 说明 (1) 至少有一个形参,第一个参数绑定调用这个方法的对象,一般命名为”self”。 (2) 无论创建多少对象,方法只有一份,并且被所有对象共享。
  2. 作用:表示对象行为。

类成员

类变量

  • 语法:
    • 定义:在类中,方法外定义变量
      • class类名:变量名 = 表达式
    • 调用:类名.变量名
      • 不建议通过对象访问类变量
  • 说明
    • 存储在类中
    • 只有一份,被所有对象共享
  • 作用:描述所有对象的共有数据。

类变量内存图

%title插图%num

类方法

  1. 语法
    1. 定义:
@classmethod
def 方法名称(cls,参数列表)
    方法体

2. 调用:类名.方法(参数列表)。不建议通过对象访问类方法

2. 说明

— 至少有一个形参,第一个形参用于绑定类,一般命名“cls”

— 使用@classmethod修饰的目的是调用类方法时可以隐式传递类。

— 类方法中不能访问实例成员,实例方法中可以访问类成员(不建议)

3. 作用:操作类变量

静态方法

1.语法

定义:

@staticmethod
def 方法名称(参数列表):
    方法体

调用:类名.方法名(参数列表)

不建议通过对象访问静态方法

2.说明

— 使用@staticmethod修饰的目的是该方法不需要隐式传参数

— 静态方法不能访问实例成员和类陈冠

3. 作用:定义常用的工具函数

封装

定义

  1. 数据角度讲,将一些基本数据类型复合成一个自定义类型。
  2. 行为角度讲,向类外提供功能,隐藏实现的细节。
  3. 设计角度讲
    1. 分而治之
      1. 将一个大的需求分解为许多类,每个类处理一个独立的功能。
      2. 拆分好处:便于分工,便于复用,可扩展性强。
    2. 封装变化
      1. 变化的地方独立封装,避免影响其他类。
    3. 高 内 聚
      1. 类中各个方法都在完成一项任务(单一职责的类)。
    4. 低 耦 合 — 类与类的关联性与依赖度要低(每个类独立),让一个类的改变,尽少影响其他类。

作用

  1. 简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。
  2. 松散耦合,降低了程序各部分之间的依赖性。
  3. 数据和操作相关联,方法操作的是自己的数据。

私有方法

  1. 作用:无需向类外提供的成员,可以通过私有化进行屏蔽。
  2. 做法:命名使用双下划线开头。
  3. 本质:障眼法,实际也可以访问。

私有成员的名称被修改为:_类名__成员名,可以通过_dict_属性或dir函数查看。

属性@property

公开的实例变量,缺少逻辑验证。私有的实例变量与两个公开的方法相结合,又使调用者的操作略显复杂。而属性可以将两个方法的使用方式像操作变量一样方法。

1、定义

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

2、调用

对象.属性名 = 数据
变量 = 对象.属性名

3、说明

— 通常两个公开的属性,保护一个私有的变量。

— @property 负责读取,@属性名.setter 负责写入

— 只写:属性名= property(None, 写入方法名)

只读示例

def __init__(self):
    self.__a = 1
@property
def a (self):
   return self.__a

__slots__

1.作用:限定一个类创建的实例只能有固定的实例变量,不能在额外添加

2.语法:

在类中定义
__slots__ = ("变量名1","变量名2"...)

3.说明,含有__slots__属性的类所创建的对象没有__dict__属性,即此实例不用字典来存储对象的实例属性。

4.优点:防止用户因错写属性的名称二发生程序错误。

5.缺点:丧失了动态语言可以在运行时为对象添加变量的灵活性。

Python是一门动态语言。通常,动态语言允许我们在程序运行时给对象绑定新的属性或方法,当然也可以对已经绑定的属性和方法进行解绑定。但是如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定。需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用。

封装内存图练习

代码部分:

# 1. 使用面向对象思想,写出下列场景:
#     玩家(攻击力)攻击敌人,敌人受伤(血量)后掉血,还可能死亡(播放动画).
#     敌人(攻击力)攻击力攻击玩家,玩家(血量)受伤后碎屏,还可能死亡(游戏结束).
# 程序调试,画出内存图.

class Player:
    """
        玩家类
    """
    def __init__(self,hp,atk):
        self.atk = atk
        self.hp = hp

    def attack(self,enemy):
        print("打死你")
        # 调用敌人受伤方法(敌人负责定义受伤逻辑)
        enemy.damage(self.atk)

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

    def __death(self):
        print("玩家死亡,游戏结束")


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

    def damage(self,value):
        self.hp -= value
        print("受伤啦")
        if self.hp <= 0:
            self.__death()

    def attack(self,player):
        print("打死你")
        player.damage(self.atk)

    def __death(self):
        print("死啦,播放动画")


p01 = Player(100,50)
e01 = Enemy(60,10)
# 玩家打敌人
p01.attack(e01)
# p01.attack(e01)
e01.attack(p01)
敌人与玩家内存图

敌人与玩家内存图

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇