进入python的世界_day26_python基础——面向对象编程、对象的独有数据、独有功能(封装)

一、面向对象编程

1.介绍

​ 首先这是一种编程思路、方法。

​ 我们以前写过的基本都是面向过程编程,是为了解决问题,将程序流程化,分步骤解决问题,核心是'过程',打个比方就是比如LOL英雄联盟这个游戏,登录功能,我们得输入对了账号密码才能登录上

​ 而面向对象编程,核心是'对象',将数据与功能整合进一个'容器'里,谁来使用这个容器就能使用什么功能,还是拿LOL英雄联盟来举例,每个英雄就是一个对象,拥有不同的数据不同的技能,我们在玩这个英雄时角色的操作技能的释放不是被写死了的,是根据我们玩家自身操控来执行对象。

2.代码实现

​ 面向对象编程这中方法落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。

  类:一个模板,模板里可以包含数据、函数,函数里实现一些功能,程序中必须先定义出类

  对象:是根据模板创建而来,通过对象可以用句点符执行类中的函数

img

  • class是关键字,表示类 该名称不可变,后面跟着的类名称建议首字母大写
  • 创建对象,类名称后加括号即可 可以拿变量名接收

!!!注意,类在定义阶段就会执行类体代码 但是属于类的局部名称空间 外界无法直接调用

3.执行对象的流程

​ 当通过对象点的方式来执行方法时,根据点指向的方法去类中找到方法,然后将对象名当作参数传给方法的第一个参数,如果方法要好几个参数,就少传一个参数,这个很好理解(注意传参位置!)

同理也可以访问类里的数据(因为类就是一个相同功能数据的集合体)

class Foo:
    # 这里可以放公共的数据
    def hahaha(self): # self 是一个形式参数,叫啥无所谓
        print("我是哈哈哈方法")

    def xixixi(self, name):
        print("我是嘻嘻嘻方法.")


a = Foo()

a.hahaha()
a.xixixi('jack')

4.在内存中的保存原理

​ 类这个整体和附带的数据、函数,在内存中只占据一份

​ 对象生成后,每一个对象,都会占一份内存地址,并且每执行一次都会产生一个全新的对象

二、对象独有数据、独有的功能

推导流程1

​ 对象生成后,用双下dict查看对象的名称空间会发现是一个空字典(看着像字典),可以通过键值对的方式增加名称进去,这时候用句点符一样可以点出名称空间对应的数据值

class Foo:

    def hahaha(self):
        print("我是哈哈哈方法")

    def xixixi(self, name):
        print("我是嘻嘻嘻方法.")


a = Foo()
a.__dict__['name'] = 'jack'
a.__dict__['age'] = 28
b = Foo()

print(a.__dict__)
>>>{'name': 'jack', 'age': 28} #属于a自己的数据
————————————————————————
print(a.name) >>> jack  # 这里pycharm已经晕了,但是逻辑是OK的

推导流程2

​ 发现如果按上述方法给对象加名称空间加东西写的代码超级多,麻烦,重复代码立马想到函数

def init(self, name, age): # self 同理形式参数,等同对象名
    self.__dict__['name'] = name
    self.__dict__['age'] = age
    
# 这样init方法就搞好了拿b 试试
init(b, 'oppo', 55)
print(b.__dict__)
>>>
{'name': 'oppo', 'age': 55} # 这样方便了一些,但是还不够

推导流程3

​ 刚刚创建的init函数是在全局名称空间,别的类产生的对象也能调用,不太好,如果想让这个函数只给某类对象专门使用,封进去

————封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。

class Foo:
    
    def __init__(self, name, age): # 变双下后,自动触发了
    self.__dict__['name'] = name
    self.__dict__['age'] = age

    def hahaha(self):
        print("我是哈哈哈方法")

    def xixixi(self, name):
        print("我是嘻嘻嘻方法.")

# 双下init是python自带语法
# 双下init自动触发,如果还要产生对象,得传对参数,不然会报错
#     a = Foo()
# TypeError: __init__() missing 2 required positional
# arguments: 'name' and 'age'

推导流程4

​ 简化优化一下

class Foo:
    
    def __init__(self, name, age): # 变双下后,自动触发了
    self.name = name # self.__dict__['name'] = name
    self.age = age   # self.__dict__['age'] = age

    def hahaha(self):
        print("我是哈哈哈方法")

    def xixixi(self, name):
        print("我是嘻嘻嘻方法.")

总结:内部的双下init方法,称为构造方法,如果在构造方法完成后产生对象,会将生成时传的参封装进构造方法构造的内容里去(封装到对象的属性)

​ 从某处调用被封装的内容

​ 调用被封装的内容时,有两种情况:

  • 通过对象直接调用
  • 通过self间接调用 ————谁来调就是谁当主人
class Foo:
    
    def __init__(self, name, age): # 变双下后,自动触发了
    self.name = name # self.__dict__['name'] = name
    self.age = age   # self.__dict__['age'] = age

    def hahaha(self):
        print("我是哈哈哈方法")

    def xixixi(self, name):
        print("我是嘻嘻嘻方法.")
        
    def chong(self):
        print(f'{self.name} 在愉快的玩耍')

a = Foo('jack', 18)
a.chong()    # 等于chong(a) 
			# 等于 print(f'{a.name}在愉快的玩耍')
>>>
jack 在愉快的玩耍
posted @ 2022-11-02 20:35  yiwufish  阅读(345)  评论(0)    收藏  举报