类和对象
面向过程和面向对象
面向过程:
1.把完成一个需求的所有步骤从头到尾逐步实现
2.根据开发需求,将某些功能独立的代码封装成一个又一个函数
3.最后完成的代码,就是顺序地调用不同的函数
特点:
- 注重步骤与过程,不注重职责分工
- 如果需求复杂,代码会变得很复杂
- 开发复杂项目,没有固定的套路,开发难度大。
面向对象:
是更大的封装,根据职责再一个对象中封装多个方法
- 在完成某一个需求前,首先确定职责–要做的事情(方法)
- 根据职责确定不同的对象,在对象内部封装不同的方法(多个)
- 最后完成的代码,就是顺序地让不同的对象调用不同的方法
特点:
- 注重对象和职责,不同的对象承担不同的职责
- 更加适合应对复杂的需求变化,是专门应对复杂项目开发,提供的固定套路
- 需要在面向过程基础上,再学习一些面向对象的语法
类
类是对一群具有相同特征或者行为的食物的一个统称,是抽象的,不能直接使用
- 特征被称为属性
- 行为被称为方法
类就相当于制造飞机的图纸,是一个模板,是负责创建对象的
对象是由类创建出来的一个具体存在,可以直接使用
由哪一个类创建出来的对象,就拥有在哪一个类中定义的属性和方法
对象就相当于用图纸制造的飞机
在程序开发中应该先有类再有对象,类只有一个,而对象可以有很多个。
不同的对象之间属性可能会各不相同
类中定义了什么属性和方法,对象中就有什么属性和方法,不可能多也不可能少
类的设计
在使用面向开发之前应该首先分析需求,确定一下,程序中需要包含哪些类。创建一个类需要满足三个要素
- 类名 这类事务的名字
- 属性 这类事务具有什么样的特征
- 方法 这类事务具有什么样的行为
面向对象基础语法
- dir内置函数:使用dir传入标识符和数据可以查看所有的方法和
- 所有以双下划线__方法名__是内置方法和属性,是可以使用的
def demo():
"""这是一个测试函数"""
print('qqq')
print(dir(demo))#查看内置方法和属性
demo()
print(demo.__doc__)#输出解释文档
序号 | 方法名 | 类型 | 作用 |
---|---|---|---|
1 | __new__ | 方法 | 创建对象时,会被自动调用 |
2 | __init__ | 方法 | 对象被初始化时,会被自动调用 |
3 | __del__ | 方法 | 对象从内存中国销毁前,会被自动调用 |
4 | __str__ | 方法 | 返回对昂的描述信息,print函数输出使用 |
定义简单的类
面向对象是更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了。
- 定义只包含方法的类
class 类名:
def 方法1(self,参数列表)
pass
def 方法2(self,参数列表)
pass
- 创建对象:当一个类定义完成之后,要使用这个类来创建对象,语法格式如下
对象变量 = 类名()
第一个面向对象程序
需求:小猫爱吃鱼,小猫要喝水
分析:定义一个猫类,定义两个方法类,不需要定义属性
class Cat:
def eat(self):
print("小猫爱吃鱼")
def drink(self):
print("小猫要喝水")
tom = Cat()
tom.eat()
tom.drink()
引用概念的强调
- 使用创建对象之后,tom变量中仍然纪录的屎对象在内存中的地址
- tom变量引用了新建的猫对象
- 使用print输出对象变量,默认情况下,是能够输出这个变量 引用的对象 是由哪一个类创建的对象,以及在内存中的地址(十六进制表示)
class Cat:
def eat(self):
print("小猫爱吃鱼")
def drink(self):
print("小猫要喝水")
tom = Cat()
tom.eat()
tom.drink()
print(tom)
addr = id(tom)
print("%d" % addr)
小猫爱吃鱼
小猫要喝水
<__main__.Cat object at 0x000002C7A1325CD0>
3056426179792
由一个类创建多的对象,这些对象有不同的地址是不同的对象。
class Cat:
def eat(self):
print("小猫爱吃鱼")
def drink(self):
print("小猫要喝水")
#创建一个猫对象
tom = Cat()
tom.name = "Tom"#单独给tom添加属性,不推荐使用这种办法
tom.eat()
tom.drink()
#再创建一个猫对象,这是不同的对象
lazy_cat = Cat()
lazy_cat.eat()
lazy_cat.drink()
<__main__.Cat object at 0x0000021AA19B5CD0>
<__main__.Cat object at 0x0000021AA19B56D0>
给对象增加属性
self解释:
- 由哪一个对象调用的方法,方法内的self就是哪一个对象的引用
在类封装的方法内部,self就表示当前调用方法的对象自己
再调用方法时,程序员不需要传递seld参数
在方法内部,可以通过self.访问对象的属性,也可以通过self.调用其他的对象方法
#解释器见到Class会跳过,等运行到可执行的代码会回到class
class Cat:
def eat(self):
# 哪一个对象调用的方法,self就是哪一个对象的引用,通过断点发现地址相同
print("%s 爱吃鱼"% self.name)
def drink(self):
print("小猫要喝水")
#创建一个猫对象
tom = Cat()
tom.name = "Tom"#添加name属性
tom.eat()#进入到class,这个时候 的self是它的引用
tom.drink()
print(tom)
#再创建一个猫对象,这是不同的对象
lazy_cat = Cat()
lazy_cat.name = "大懒猫"#给lazy_cat添加对象
lazy_cat.eat()#进入类,这个时候的self是lazy_cat的对象
lazy_cat.drink()
print(lazy_cat)
结果:
Tom 爱吃鱼
小猫要喝水
<__main__.Cat object at 0x0000021D60E55CD0>
大懒猫 爱吃鱼
小猫要喝水
<__main__.Cat object at 0x0000021D60E55C10>
初始化方法
在日常开发中,不推荐在类的外部给对象增加属性,如果在运行时,没有找到属性,程序会报错,对象应该包含由哪些属性,应该封装在类的内部
-的当使用类名()创建对象时,会 自动 执行以下操作:
- 为对象在内存中 分配空间 – 创建对象
- 为对象的属性 设置初始值 – 初始化方法(init)
这个初始化方法就是__init__方法,这是对象的内置方法,用来定义一个类具有哪些属性的方法。
class Cat:
def __init__(self):
print("这是一个初始化方法")
#使用类名()创建对象的时候,会自动调用初始化方法__init__
tom = Cat()
在初始化方法内部定义属性
- 在__init__方法内部使用self.属性名 = 属性的初始值 就可以定义属性
- 定义属性之后,再使用Cat类创建的对象,都会有该属性
class Cat:
def __init__(self):
self.name = "tom"
print("这是一个初始化方法")
#使用类名()创建对象的时候,会自动调用初始化方法__init__
tom = Cat()
print(tom.name)
改造初始化方法
前边指定的属性是固定的,如果希望再创建对象的同时,就设置对象的属性,可以对__init__方法进行改造
- 把希望设置的属性值,定义成__init__方法的参数
- 再方法内部使用self.属性 = 形参 接收外部传递的参数
- 在创建对象时,使用类名(属性1,属性2…)调用
class Cat:
def __init__(self,newname):#使用形参的形式传递参数
# self.name = "tom"
self.name = newname
print("这是一个初始化方法")
def eat(self):
print("%s 爱吃鱼"% self.name)
#使用类名()创建对象的时候,会自动调用初始化方法__init__
tom = Cat("Tom")
tom.eat()
lazy_cat = Cat("大懒猫")
lazy_cat.eat()