一、面向对象的概念
面向对象编程**(Object Oriented Programming)**
简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
面向对象的几大核心特性:
Class 类:一个类指相同事物相同特征提取,把相同的属性方法提炼出来定义在类中
Object 对象:一个对象是类的实例,对象是具体的,类是抽象
封装:对外部世界隐藏对象的工作细节
继承:一个子类继承基类的字段和方法
多态:对不同类的对象使用同样的操作
二、类和对象
(一)类
万物皆对象,任何一个能够看得到、摸得着的具体实体,均可以看做对象。
类是抽象的概念,仅仅是模板 比如说:“学生”
对象是一个你能够看得到、摸得着的具体实体:1班小明,2班小红, 3班小荷
在Python中,所有数据类型都可以视为类,当然也可以自定义对象的数据类型。自定义的对象数据类型就是面向对象中的类(Class)的概念。
根据类来创建对象被称为实例化。
user1 = 12
user2 = 'Bob'
user3 = []
print(type(user1))
print(type(user2))
print(type(user3))
结果为:
<class 'int'>
<class 'str'>
<class 'list'>
类是模子,定义对象将会拥有的特征(属性)和行为(方法)。
(二)对象
现实生活中的几个对象实例:
(1)学生类型
属性: 姓名, 年龄,身高, 班级
行为: 学习,
(2)老师类型:
属性: 姓名, 年龄,身高
行为: 上课,批改作业
对象的特征包含: 属性,方法(操作,行为,操作数据的函数)
(1)属性——对象具有的各种特征。 每个对象的每个属性都拥有特定值。 例如:学生小明,小红的班级不一样。
(2)方法——对象执行的操作(通常会改变属性的值)。 学生对象的方法—学习。 老师对象的方法----上课,批改作业。
总结 :
(1)对象:用来描述客观事物的一个实体,由一组属性和方法构成
(2)对象同时具有属性和方法两项特性。 对象的属性和方法通常被封装在一起,共同体现事物的特性, 二者相辅相承,不能分割。
(三)从对象抽象出类
抽取出下列对象的共同特征(属性和方法)
如上述图片, 都是手机, 都有属性: 价格,品牌; 都可以进这些行为: 打电话,上网。 因此可以定义一个手机类。
再次强调
(1)类是抽象的概念,仅仅是模板。 类是模子,定义对象将会拥有的特征(属性)和行为(方法)。 比如说:“学生”, 类定义了学生这种类型属性(姓名,班级,年龄)和方法(学习)。
(2)对象是一个你能够看得到、摸得着的具体实体: 1班小明,2班小红, 3班小荷,这些具体的学生都具有学生类型中定义的属性和方法,不同的是他们各自的属性不同。
**根据类来创建对象被称为实例化。**
三、创建类
首先创建类的语法
class ClassName(object):
pass
python中使用class关键字修饰类,类名一般采用首字母大写,小阔号里面表示继承,
注:类名后面有括号的类,称为新式类,括号里面的内容是父类的名称;程序中所有类的父类都是 object
可以理解为定义了 一个数据类型。
(一)类属性
先创建一个简单的类:
class Phone:
brand = 'xiaomi'
price = 4999
print( Phone)
print( Phone.price)
# <class '__main__.Phone'>
# 4999
其中 <class ‘main.Phone’> 表明创建了Phone类,可以理解为定义了 一个数据类型为Phone。price为类属性,可以通过类名访问、修改。并且通过Phone类实例化的对象都可以调用price属性及其属性值。
注意:类属性和实例属性的区别
类变量和实例变量
创建对象时,对象在内存中申请了与类空间大小相同的空间;此时对对象而言,实例属性是对象的特有特征,实例的属性和类属性分别存储在对应的dict中,故对象的实例属性可以自定义添加、修改。但是对象通过类实例化进行创建,因此可以通过对象名对类属性进行调用。
当我们输出查找的时候,它的顺序是: 实例dict->类的dict->基类
那么我们区分类变量和实例变量的目的是什么呢,他们有什么区别:很重要的一点,实例属性为每个实例独有,类属性为所有实例共享
class Phone:
brand = 'xiaomi'
price = 4999
phone1 = Phone() # 创建phone1对象
print(phone1.price) # 未自定义phone1 对象的price属性, 但是可以调用类中的price属性及其值
# 4999
Phone.price = 9999999 # 修改类属性值
print(phone1.price) # 当类属性price值修改后, phone1调用类中的price属性,其属性值同步修改
# 9999999
phone1.price = 1888 # 建立实例属性,当查找对象某值时, 先在实例空间查找, 若没有则 查找 类属性
print(phone1.price)
# 1888
类变量的用途:大家共用的属性放在类变量中
(二)类的方法
1>类的方法 ==== 函数
2>在类中定义的函数叫做方法
3>self 实质上是类实例化后的对象本身
4>类的实例化产生的就是对象:object;;把抽象的类创造出实际存在的事物
参数 :self 的理解
class Phone:
brand = 'xiaomi'
price = 4999
def call(self): # Phone类里面实例方法:call
print('self----------->', self)
phone1 = Phone()
print(phone1)
print(phone1.call())
# <__main__.Phone object at 0x0000017550224460>
# self-----------> <__main__.Phone object at 0x0000017550224460>
如上述代码可以看到 实例phone1与self相同,都是在内存空间地址相同的Phone类对象。
理解: 类的实例方法中第一个参数必须为self ,意味着当通过 “对象名.方法名 ” 调用函数时,是对实例所处的内存空间进行操作。对类没有影响。相当于地址传递。
可以在类的实例方法中通 self 参数,调用 实例对象已经添加或修改的属性,即实例内存空间中的值。
class Phone:
brand = 'xiaomi'
price = 4999
def call(self): # Phone类里面方法:call
print('self----------->', self)
print('通过self 可以在类中使用在类外定义的实例属性: ', self.name)
phone1.name = '呼叫中。。。。'
print(phone1)
print(phone1.call())
结果为:
<__main__.Phone object at 0x000001754EB86160>
self-----------> <__main__.Phone object at 0x000001754EB86160>
通过self 可以 在类中使用 在类外定义的实例属性: 呼叫中。。。。
理解: self 是实例的地址,在实例空间中添加了 name属性。当实例调用类中的实例方法时,self传入实例的地址,故可以在类方法中调用实例属性。
** 问题: 如上例, 若有的对象没有name实例属性,调用类方法call()时,其中的self.name就会报错。
在日常开发中,不推荐在 类的外部 给对象增加属性。
如果在运行时,没有找到属性,程序会报错。
对象应该包含有哪些属性,应该 封装在类的内部。
故python提供了 __init__方法解决
init(初始化方法)
当使用‘ 类名()’ 创建对象时,会 自动 执行以下操作:
1)为对象在内存中 分配空间 —— 创建对象(调用new,以后说)
2)为对象的属性 设置初始值 —— 初始化方法(调用init并且将第一步创建的对象,通过self参数传给init)
这个 初始化方法 就是 init 方法,init 是对象的内置方法(有的书也叫魔法方法,特殊方法)
理解 init(初始化方法),涉及到内存空间中的传递与搜索;
(1)使用__new__创建对象,向内存中申请了一个大小与类空间大小相同的 内存空间,并有其特定的地址。
**(2)注意: 申请内存空间后,并没有将地址赋给 对象名;而是向类中查找有没有 init 魔术方法,;
如果没有则 把申请的内存地址 赋给对象名 ;
若有则 执行__init__方法,__init__方法必定有 self参数 ,此时 self参数代表的是 对象名 申请的地址;
(3) 执行完__init__方法后, 地址赋给 对象名。此时对象名对应的空间已经存储了 __init__方法操作的各项值。
class Phone:
def __init__(self, brand, price):
self.brand = brand
self.price = price
phone1 = Phone('huawei', '4999')
# huawei 4999
理解:在创建对象时,在类名()括号中,添加初始值;使phone1对象所在的内存空间存储了,brand,price值。
实例方法
class Cat:
type = '猫'
# 通过__init__初始化的特征
def __init__(self, nickname, age, color):
self.nickname = nickname
self.age = age
self.color = color
# 动作:方法
def eat(self, food):
print('{}喜欢吃{}'.format(self.nickname, food))
def catch_mouse(self, color, weight):
print('{},抓了一只{}kg的,{}的大老鼠!'.format(self.nickname, weight, color))
def sleep(self, hour):
if hour < 5:
print('乖乖!继续睡觉吧!')
else:
print('赶快起床出去抓老鼠!')
def show(self):
print('猫的详细信息:')
print(self.nickname, self.age, self.color)
# 创建对象
cat1 = Cat('花花', 2, '灰色')
# 通过对象调用方法
cat1.catch_mouse('黑色', 2)
cat1.sleep(8)
cat1.eat('小金鱼')
cat1.show()
结果为:
花花,抓了一只2kg的,黑色的大老鼠!
赶快起床出去抓老鼠!
花花喜欢吃小金鱼
猫的详细信息:
花花 2 灰色
一般来说类中的方法,第一个参数是 self ,意味着 通过对象调用; 称为实例方法;调用时传参数,参数可以在实例方法中使用
关于python面向对象的:类方法,静态方法,封装,继承,多态 将在下篇写到。
以上理解:为个人从老师课堂讲解获得,暂时未查到文献,可能有部分错误。