Python 面向对象编程---封装

Python面向对象编程 Object Oriented Programming(OOP)----封装

首先明白面向对象和面向过程具体的区别和特点,有利于更好的明白它们各自的优势

面向过程

  1. 把完成某一个需求的 所有步骤 从头到尾 逐步实现
  2. 根据开发需求,将某些 功能独立 的代码 封装 成一个又一个 函数
  3. 最后完成的代码,就是顺序地调用 不同的函数

特点

  1. 注重 步骤与过程,不注重职责分工
  2. 如果需求复杂,代码会变得很复杂
  3. 开发复杂项目,没有固定的套路,开发难度很大!

面向对象

  1. 在完成某一个需求前,首先确定 职责 —— 要做的事情(方法)
  2. 根据 职责 确定不同的 对象,在 对象 内部封装不同的 方法(多个)
  3. 最后完成的代码,就是顺序地让 不同的对象 调用 不同的方法

特点

  1. 注重 对象和职责,不同的对象承担不同的职责
  2. 更加适合应对复杂的需求变化,是专门应对复杂项目开发,提供的固定套路
  3. 需要在面向过程基础上,再学习一些面向对象的语法

知道了面向对象和面向过程的区别和特点,我们需要了解面向对象的两个核心概念 类 和 对象

类和对象

  • 类是对一群具有 相同 特征 或者 行为 的事物的一个统称,是抽象的,不能直接使用特征 被称为 属性行为 被称为 方法
  • 就相当于制造飞机时的图纸,是一个 模板,是 负责创建对象的

对象

  • 对象由类创建出来的一个具体存在,可以直接使用
  • 哪一个类 创建出来的 对象,就拥有在 哪一个类 中定义的:属性和方法
  • 对象 就相当于用 图纸 制造 的飞机
class Person:   # 类就是抽象的一般对象,含有对象共有的属和方法,一个类可以有多个对象
    name = ''
    age = 0
    def works(self):
        self.work = ''
        pass

if __name__ == '__main__':
    xiaoming = Person()    # 用Person类实例化一个xiaoming对象,我们可以对该对象的属性进行赋值,可以调用该对象所属类的方法 
    xiaoming.name = '小明'
    xiaoming.age = 18
    xiaoming.work = '学生' 

学习完类和对象的定义和关系,接下俩就是具体进行类的封装和实例化对象

常用类函数

序号方法名类型作用备注
01__new__方法创建对象时,会被 自动 调用类比C++的无参构造
02__init__方法对象被初始化时,会被 自动 调用类比C++含参构造函数
03__del__方法对象被从内存中销毁前,会被 自动 调用类比C++析构函数
04__str__方法返回对象的描述信息print 函数输出使用Python独有
  • __init__

调用时机: 在创建对象之后,会立即调用.

作用:
1. 用来给对象添加属性,给对象属性一个初始值(构造函数)
2. 代码的业务需求,每创建一个对象,都需要执行的代码可以写在 __init__
注意点: 如果 __init__ 方法中,给出了 self 之外的形参,那么在创建的对象的时候,需要给额外的形参传递实参值 类名(实参)

-__str__

调用时机:
1. print(对象), 会自动调用 __str__ 方法, 打印输出的结果是 __str__ 方法的返回值
2. str(对象) 类型转换,将自定义对象转换为字符串的时候, 会自动调用

作用:
1. 打印对象的时候,输出一些属性信息
2. 需要将对象转换为字符串类型的时候
注意点:
方法必须返回一个字符串,只有 self 一个参数

  • __del__

调用时机: 就是析构函数
对象在内存中被销毁删除的时候(引用计数为 0)会自动调用 del 方法
1. 程序代码运行结束,在程序运行过程中,创建的所有对象和变量都会被删除销毁
2. 使用 del 变量 , 将这个对象的引用计数变为 0(就是从内存中删除数据),会自动调用 del 方法

作用:
对象被删除销毁的时候,要书写的代码可以写在 __del__中,一般很少使用

self变量

哪一个对象 调用的方法,方法内的 self 就是 哪一个对象的引用,和C++中的this指针相同,区别是C++中的this不在参数列表中,隐式存在,Python中,是显含在参数列表中的,以默认形参存在,程序员调用时不用传入

  • 在类封装的方法内部,self 就表示 当前调用方法的对象自己
  • 调用方法时,程序员不需要传递 self 参数
  • 在方法内部
    • 可以通过 self. 访问对象的属性
    • 也可以通过 self. 调用其他的对象方法
  • 继承中,需要明白什么时候需要在调用方法的括号中加self,什么时候需要在属性前加self

初始化对象时设置初始值

类似于C++中的含参构造函数

class A:
    def __init__(self,name,age):
        self.name = name    # 这里也可以定义默认参数
        self.age = age

    def show(self):
        print("我叫%s,今年%d"%(self.name,self.age))

if __name__ == '__main__':
    a = A("小明",18)     # 通过传入参数设置初始值
    a.show()           # 我叫小明,今年18

具体案列

针对面向对象,多练习一些例子,明白如何封装,如何调用,会加快自己对面向对象 的理解
具体步骤:
1.第一步 —— 将 属性方法 封装 到一个抽象的
2.外界 使用 创建 对象,然后 让对象调用方法
3.对象方法的细节 都被 封装类的内部

案列1

小明小美 都爱跑步, 小明 体重 75.0 公斤, 小美 体重 45.0 公斤, 每次 跑步 都会减少 0.5 公斤,每次 吃东西 都会增加 1 公斤,在进行多次跑步吃东西操作之后,打印小明和小美的体重

分析
小明和小美都是对象,是Person类的实例化对象,题目要求有吃东西跑步两种操作,则Person类中有该两种方法,需要输出体重,则可以通过__str__函数返回该对象体重

class Person:
    def __init__(self,name,weight):
        self.name = name
        self.weight = weight

    def eat(self):
        self.weight += 1.0

    def run(self):
        self.weight -= 0.5

    def __str__(self):
        return "我叫%s,现在的体重为%.02fkg"%(self.name,self.weight)
# 这里稍微注意一下输出格式,因为如果用%d,则会之间舍弃小数,应该用%.02f输出格式
if __name__ == '__main__':
    xiaoming = Person("xiaoming",75)
    xiaomei =Person("xiaomei",45)
    print(xiaoming)    # 我叫xiaoming,现在的体重为75.00kg
    print(xiaomei)     # 我叫xiaomei,现在的体重为45.00kg
    xiaoming.eat()
    xiaoming.run()
    print(xiaoming)    # 我叫xiaoming,现在的体重为75.50kg
    xiaomei.run()
    xiaomei.eat()
    print(xiaomei)     # 我叫xiaomei,现在的体重为45.50kg

案列2

1.定义一个Furniture类,初始化定义namearea属性
2.创建一个类Home,初始化地址address 房屋面积area, 家具列表list属性
3.定义方法add_furniture 容纳家具 添加家具,并且计算剩余面积
4.创建一个对象jia1(北京, 占地面积1000),创建对象双人床bed,sofa 分别占地面积6,10添加到jia1中,计算剩余面积,并且打印
打印格式是房子地理位置在xx,房子面积xx,剩余面积是xx,家具有xx

分析
宏观上可知是定义两个类,一个是Fruniture类,一个是Home类,实例化两个Fruniture对象sofe和bed,将这两个对象添加到Home对象jia1中.
微观上,Home类中应该有属性,家具列表,地址,房屋面积,剩余面积,方法有添加家具,Fruniture类中有属性:名字,占地面积,剩下的就是细节完善

class Fruniture:
    def __init__(self,name,area):
        self.name = name
        self.area = area

class Home:
    list = []
    def __init__(self,address,area):
        self.address = address
        self.area = area
        self.remaing = area
    def add_fruniture(self,fru):
        self.list.append(fru)
        self.remaing = self.remaing - fru.area

    def pr(self):
        print("房子地理位置在", self.address, "房子面积:", self.area, "剩余面积是:",self.remaing, "家具有:", end="")
        for x in jia1.list:  # 这里利用x在list中遍历 是遍历对象 要想拿出名字,还需要.name
            print(x.name, end=",")

if __name__ == '__main__':
    jia1 = Home("北京",1000)
    bed = Fruniture("双人床",6)
    sofa = Fruniture("沙发",10)
    jia1.add_fruniture(bed)
    jia1.add_fruniture(sofa)
    jia1.pr()  
    # 房子地理位置在 北京 房子面积: 1000 剩余面积是: 984 家具有:双人床,沙发,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Philo`

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值