面向对象编程基本概念
面向对象编程——Object Oriented Programing 简写OOP
面向对象三大特性
1.封装:根据职责将属性和方法封装到一个抽象的类中
2.继承:实现代码的重用,相同的代码不需要重复的编写
3.多态:不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
过程和函数的区别
过程:只能执行,没有返回值
函数:不仅能执行,还可以返回结果
面向过程:怎么做
1.把完成某个需求的所有步骤从头到尾逐步实现
2.根据开发需求,将某些功能独立的代码封装成一个个函数
3.最后完成的代码,就是顺序地调用不同的函数
特点:
1.注重过程与步骤,不注重职责分工
2.如果需求复杂,代码会变得很复杂
3.开发复杂项目,没有固定套路,开发难度大
面向对象:谁来做
相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
1.在完成某个需求前,首先确定职责——要做的事情(方法)
2.根据职责确定不同的对象,在对象内部封装不同的方法(多个)
3.最后完成的代码,就是顺序的让不同的对象调用不同的方法
特点:
1.注重对象和职责,不同的对象承担不同的职责
2.更加适合应对复杂的需求变化,是专门应对复杂项目开发,提供的固定套路
3.需要在面向过程基础上,再学习一些面向对象的语法
类和对象
类
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用
特征被称为属性
行为被称为方法
类相当于图纸或模版,是负责创建对象的
对象
对象是由类创建出来的一个具体存在,可以直接使用
由哪一个类创建出来的对象,就拥有在哪一个类中定义的属性和方法
对象就相当于用图纸制造的飞机
在程序开发中,应该先有类,再有对象
类的设计
在使用面向对象开发前,应该首先分析需求,确定一下,程序中需要包含哪些类
类的三要素
1.类名:要满足大驼峰命名法,如FirstName
2.属性:这类事物具有什么样的特征
3.方法:这类事物具有什么样的行为
面向对象基础语法
dir内置函数
在Python中有两种方法验证对象:
1.在标识符/数据后输入一个.,然后按下Tab键,iPython会提示该对象能够调用的方法列表
2.使用内置函数dir传入标识符/数据,可以查看对象内的所有属性及方法
__方法名__格式的方法是Python提供的内置方法/属性
方法名 | 类型 | 作用 |
---|---|---|
__new__ | 方法 | 创建对象时会被自动调用 |
__init__ | 方法 | 对象被初始化时,会被自动调用 |
__del__ | 方法 | 对象被从内存中销毁时,会被自动调用 |
__str__ | 方法 | 返回对象的描述信息,print函数输出使用 |
定义简单的类(只包含方法)
面向对象是更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了。
例1:定义一个只包含方法的类
Class 类名:
def 方法1(self, 参数列表):
pass
def 方法2(self, 参数列表):
pass
注:与普通方法的区别在于第一个参数必须是self
关于self
由哪一个对象调用的方法,方法内self就是哪一个对象的引用
在类封装的方法内部,self就表示当前调用的对象自己
调用方法时,程序员不需要传递self参数,如Cat.eat()括号中不需要添加self
在方法内部,可以用self.访问对象的属性,也可以通过self.调用其他的对象方法
创建对象
当一个类定义完成后,要使用这个类来创建对象,语法如下:
对象变量 = 类名()
使用同一个类可以创建不同的对象,在内存中的表现是:当创建一个类的对象时,会在内存中先创建一个类,然后对象指向类的地址,如果再创建一个对象则优惠创建一个类,再次分配地址
初始化方法
当使用类名()创建对象时,会自动执行以下操作:
1.为对象在内存中分配空间——创建对象
2.为对象的属性设置初始值——初始化方法(init)
这个初始化方法就是__init__方法,是对象的内置方法
该方法是专门用来定义一个类具有哪些属性的方法
而在创建对象时会自动调用初始化方法,如下例:
>>class Cat:
def __init__(self):
print("啦啦啦")
>>tom = Cat()
>啦啦啦
此时并未主动调用__init__,但在创建tom时就会自动调用,打印了“啦啦啦”
在__intit__方法内使用self.属性名 = 属性的初始值就可以定义属性
例:
>>class Cat:
def __init__(self, new_name):
self.name = new_name
def eat():
print('%s 爱吃鱼' % self.name)
>>tom = Cat("TOM")
>>tom.eat()
>TOM 爱吃鱼
一个对象的属性可以试试另一个类创建的对象
在定义属性时,如果不知道设置什么初始值,可以设置为None:None关键字表示什么都没有,表示一个空对象,没有方法和属性,是一个特殊的常量,可以将None赋值给任意一个变量
__del__方法
已知当使用类名()创建对象时,为对象分配完空间后,自动调用__init__方法,而当一个对象被从内存中销毁前,会自动调用__del__方法
应用场景:
__init__改造初始化方法,可以让创建对象更加灵活
__del__如果希望对象被销毁前,再做一些事情,可以考虑一下__del__方法
生命周期:
一个对象从调用类名()创建,生命周期开始
一个对象的__del__方法一旦被调用(如:del 对象名),生命周期结束
在对象的生命周期内,可以访问对象属性,或者让对象调用方法
__str__方法
在Python中,使用print输出对象变量,默认情况下会输出这个变量引用的对象是由哪一个类创建的对象,以及在内存中的地址(十六进制表示)
如果在开发中,希望使用print输出对象变量时,能够打印自定义的内容,就可以利用__str__这个内置方法了
注意:__str__方法必须返回一个字符串
例:
>>class Cat:
def __init__(self, new_name):
self.name = new_name
print('%s来了' % self.name)
def __del__(self):
print('%s走了' % self.name)
def __str__(self):
return '%s是只猫' % self.name
>>tom = Cat('Tom')
>Tom来了
>Tom走了 # 此处为在idle中演示,因为即时结束,所以触发了__del__
>>print(tom)
>Tom是只猫
私有属性和私有方法
应用场景
在实际开发中,对象的某些属性或方法可能只希望在对象的内部使用,而不希望在外部被访问到,私有属性就是对象不希望公开的属性,私有方法就是对象不希望公开的方法
定义方式
在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法
继承
概念:
子类拥有父类的所有方法和属性
语法:
class 类名(父类名):
pass
方法的重写
当父类的方法实现不能满足子类需求时,可以对方法进行重写(override)
重写父类方法有两种情况:
1.覆盖父类的方法:如果在开发中,父类的方法实现和子类的方法实现完全不同,就可以用覆盖的方式,在自类中重新编写父类的方法实现,具体的实现方式就相当于在子类中定义了一个和父类同名的方法并且实现
2.对父类方法进行扩展:如果在开发中,子类的方法实现中包含父类的方法实现,就可以使用扩展的方式,具体步骤如下:
1.在子类中重写父类的方法
2.在需要的位置使用super().父类方法来调用父类方法的执行
3.代码其他的位置针对子类的需求,编写子类特有的代码实现
例:
>>class Dog():
def bark(self):
print("汪汪")
def eat(self):
print("eating shit")
>>class XiaoTianQuan(Dog):
def fly(self):
print("I believe I can fly!")
def bark(self):
print("嗷嗷嗷")
super().bark