一、面向对象(OOP)基本概念
面向对象编程 —— Object Oriented Programming
简写 OOP
1.1 过程和函数
-
过程 是早期的一个编程概念
-
过程 类似于函数,只能执行,但是没有返回值
-
函数 不仅能执行,还可以返回结果
1.2 面相过程和面相对象基本概念
(1)面相过程 —— 怎么做?
-
把完成某一个需求的所有步骤从头到尾逐步实现
-
根据开发需求,将某些功能独立的代码封装成一个又一个函数
-
最后完成的代码,就是顺序地调用 不同的函数
特点
-
注重步骤与过程,不注重职责分工
-
如果需求复杂,代码会变得很复杂
-
开发复杂项目,没有固定的套路,开发难度很大!
(2) 面向对象 —— 谁来做?
相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
-
在完成某一个需求前,首先确定职责 —— 要做的事情(方法)
-
根据职责确定不同的对象,在对象内部封装不同的方法(多个)
-
最后完成的代码,就是顺序地让 不同的对象调用不同的方法
特点
-
注重 对象和职责,不同的对象承担不同的职责
-
更加适合应对复杂的需求变化,是专门应对复杂项目开发,提供的固定套路
-
需要在面向过程基础上,再学习一些面向对象的语法
二、类和对象
01. 类和对象的概念
1.1 类
-
类是对一群具有 相同特征或者行为的事物的一个统称,是抽象的,不能直接使用
- 特征 被称为 属性
- 行为 被称为 方法
- 类就相当于制造飞机时的图纸,是一个模板,是负责创建对象的
1.2 对象
-
对象是由类创建出来的一个具体存在,可以直接使用
-
由哪一个类创建出来的对象,就拥有在哪一个类中定义的:
- 属性
- 方法
-
对象就相当于用图纸制造的飞机
在程序开发中,应该先有类,再有对象
02. 类和对象的关系
-
类是模板,对象是根据类这个模板创建出来的,应该先有类,再有对象
-
类 只有一个,而 对象 可以有很多个
-
不同的对象 之间 属性 可能会各不相同
-
- 类 中定义了什么 属性和方法,对象 中就有什么属性和方法,不可能多,也不可能少
03. 类的设计
在使用面相对象开发前,应该首先分析需求,确定一下,程序中需要包含哪些类!
在程序开发中,要设计一个类,通常需要满足一下三个要素:
-
类名 这类事物的名字,满足大驼峰命名法
-
属性 这类事物具有什么样的特征
-
方法 这类事物具有什么样的行为
大驼峰命名法
-
每一个单词的首字母大写
-
单词与单词之间没有下划线
3.1 类名的确定
名词提炼法分析整个业务流程,出现的名词,通常就是找到的类
3.2 属性和方法的确定
-
对 对象的特征描述,通常可以定义成 属性
-
对象具有的行为(动词),通常可以定义成 方法
实例:
-
小明 今年 18 岁,身高 1.65,每天早上 跑 完步,会去 吃 东西
-
小强 今年 16 岁,身高 1.60,小强不跑步,小强喜欢 吃 东西
三、面相对象基础语法
01. dir
内置函数
在Python中对象几乎是无所不在的,我们之前学习的变量、数据、函数都是对象;
使用内置函数 dir传入标识符 / 数据,可以查看对象内的所有属性及方法;
提示: __方法名__ 格式的方法是 Python 提供的 内置方法 / 属性
序号 | 方法名 | 类型 | 作用 |
---|---|---|---|
01 | __new__ |
方法 | 创建对象时,会被 自动 调用 |
02 | __init__ |
方法 | 对象被初始化时,会被 自动 调用 |
03 | __del__ |
方法 | 对象被从内存中销毁前,会被 自动 调用 |
04 | __str__ |
方法 | 返回对象的描述信息,print 函数输出使用 |
02. 定义简单的类(只包含方法)
面向对象是更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了!
2.1 定义只包含方法的类
class 类名:
def 方法1(self, 参数列表):
pass
def 方法2(self, 参数列表):
pass
-
方法的定义格式和之前学习过的函数几乎一样
-
区别在于第一个参数必须是self
注意:类名的命名规则 要符合大驼峰命名法
2.2 创建对象
对象变量 = 类名()
2.3 第一个面向对象程序
class Dog:
"""这是一个狗类"""
def eat(self):
print("eat....")
def run(self):
print("run....")
dog = Dog()
dog.eat()
dog.run()
引用的概念
在Python中使用类创建对象之后,dog变量中仍然记录的是对象在内存中的地址
也就是dog变量引用了新建的狗对象
使用print输出对象变量,默认情况下,是能够输出这个变量引用的对象是由哪一个类创建的对象,以及在内存中的地址(十六进制表示)
提示:在计算机中,通常使用十六进制表示内存地址
-
十进制 和 十六进制 都是用来表达数字的,只是表示的方式不一样
-
十进制 和 十六进制 的数字之间可以来回转换
-
%d
可以以 10 进制 输出数字 -
%x
可以以 16 进制 输出数字
03. 方法中的 self
参数
3.1给对象增加属性
在python中,要给对象设置属性,非常的容易,但是不推荐使用,因为:对象属性的封装应该封装在类的内部
只需要在类的外部的代码中直接通过 . 设置一个属性即可;
dog.name = "萨摩"
3.2 使用 self
在方法内部输出狗的名字
由哪一个对象调用的方法,方法内的 self 就是哪一个对象的引用。
-
在类封装的方法内部,self 就表示 当前调用方法的对象自己
-
调用方法时,程序员不需要传递
self
参数 -
在方法内部
-
可以通过 self. 访问对象的属性
-
也可以通过 self. 调用其他的对象方法
-
在 类的外部,通过 变量名. 访问对象的 属性和方法
-
在 类封装的方法中,通过 self. 访问对象的 属性和方法
class Dog:
"""这是一个狗类"""
def eat(self):
print("%s 正在 eat.... " %self.name)
def run(self):
print("%s 正在 run.... " %self.name)
dog = Dog()
dog.name = "萨摩"
dog.eat()
dog.run()
04. 初始化方法
4.1 初始化方法
当使用类名()创建对象时,会 自动 执行以下操作:
- 为对象在内存中 分配空间 —— 创建对象
- 为对象的属性 设置初始值 —— 初始化方法(init)
这个 初始化方法 就是__init__方法,__init__是对象的内置方法
__init__方法是 专门 用来定义一个类 具有哪些属性的方法!
4.2 在初始化方法内部定义属性
-
在__init__方法内部使用 self.属性名 = 属性的初始值就可以定义属性
-
定义属性之后,再使用Dog类创建的对象,都会拥有该属性
class Dog:
def __init__(self):
print("这是初始化方法")
# 定义用Dog类创建的狗对象都有一个name属性
self.name = "萨摩"
def eat(self):
print("%s正在吃"%self.name)
# 使用类名()创建对象的时候了,会自动调用初始化方法__init__
samo = Dog()
samo.eat()
4.3 改造初始化方法 —— 初始化的同时设置初始值
在开发中,如果希望在创建对象的同时,就设置对象的属性,可以对 __init__方法进行改造
-
把希望设置的属性值,定义成__init__方法的参数
-
在方法内部使用 self.属性 = 形参 接收外部传递的参数
-
在创建对象时,使用 类名(属性1, 属性2...) 调用
class Dog:
def __init__(self,name):
print("这是初始化方法")
self.name = name
def eat(self):
print("%s正在吃" % self.name)
samo = Dog("萨摩")
samo.eat()
05. 内置方法和属性
序号 | 方法名 | 类型 | 作用 |
---|---|---|---|
01 | __del__ |
方法 | 对象被从内存中销毁前,会被 自动 调用 |
02 | __str__ |
方法 | 返回对象的描述信息,print 函数输出使用 |
5.1 __del__
方法
-
在python中
- 当使用类名()创建对象时,为对象分配完空间后,自动调用__init__方法
- 当一个对象被从内存中销毁 前,会自动调用__del__方法
-
应用场景
- __init__改造初始化方法,可以让创建对象更加灵活
- __del__如果希望在对象被销毁前,再做一些事情,可以考虑一下 __del__方法
- 生命周期
- 一个对象从调用类名()创建,生命周期开始
- 一个对象的__del__方法一旦被调用,生命周期结束
- 在对象的生命周期内,可以访问对象属性,或者让对象调用方法
class Dog:
def __init__(self,name):
self.name = name
print("%s 来了" % self.name)
def __del__(self):
print("%s 去了" % self.name)
samo = Dog("萨摩") # samo是一个全局变量
print(samo.name)
del samo # del关键字可以删除一个对象
5.2 __str__
方法
-
在python中,使用print输出对象变量,默认情况下,会输出这个变量引用的对象是由哪一个类创建的对象,以及在内存中的地址(十六进制表示)
-
如果在开发中,希望使用print输出对象变量时,能够打印自定义的内容,就可以利用 __str__这个内置方法了
注意 __str__方法必须返回一个字符串
class Dog:
def __init__(self,name):
self.name = name
print("%s 来了" % self.name)
def __del__(self):
print("%s 去了" % self.name)
def __str__(self):
return "小狗%s" % self.name
samo = Dog("萨摩")
print(samo)
四、私有属性和私有方法
01. 应用场景及定义方式
1.1应用场景
-
在实际开发中,对象 的 某些属性或方法 可能只希望 在对象的内部被使用,而 不希望在外部被访问到
-
私有属性 就是 对象 不希望公开的 属性
-
私有方法 就是 对象 不希望公开的 方法
1.2定义方式
-
在 定义属性或方法时,在 属性名或者方法名前 增加 两个下划线,定义的就是 私有 属性或方法
class Person(object):
def __init__(self, name):
self.name = name
self.__age = '保密'
def __secret(self):
print('性别保密')
xiaohei = Person('xiaohei')
print(xiaohei.__age) # 私有属性外部不能访问
print(xiaohei.__secret()) # 私有方法外部不能访问
02. 伪私有属性和私有方法
提示:在日常开发中,不要使用这种方式,访问对象的私有属性或私有方法
python中,并没有 真正意义 的 私有
- 在给 属性、方法 命名时,实际是对 名称 做了一些特殊处理,使得外界无法访问到
- 处理方式:在 名称 前面加上 _类名 => _类名__名称
print(xiaohei._Person__age) # 私有属性外部不能访问
print(xiaohei._person__secret()) # 私有方法外部不能访问