一、面向对象技术简介
面向过程: 根据业务逻辑从上到下写代码
也就是之前做的一些小练习
面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程
最具代表性的列表、字符串等等都是面向对象
面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的属性和方法),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙互相缠斗着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 方法:类中定义的函数。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 实例化:创建一个类的实例,类的具体对象。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
- 实例变量:定义在方法中的变量,只作用于当前实例的类。
- 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
二、创建类
使用 class 语句来创建一个新类,class 之后为类的名称并以冒号结尾:
class 类名称:
类的属性
类的方法
#创建一个Python学员的类
class Python学员: # 习惯性: 类使用大写字母开头
"""类功能: 用于记录所有Python学员"""
# 类属性: 将来用这个类实例化出的所有对象都有的属性
eyes_num = 2 # 所有用这个类实例化的对象一定都有2只眼睛
hair_color = 'black'
2.1 类的实例化(对象)
c1 = Python学员()
c1 = Python学员()
2.2 属性的引用
c1.eyes_num
>>2
c1.hair_color
>>'black'
c2.eyes_num
>>2
c2.hair_color
>>'black'
2.3 类属性的操作
属性可以重新赋值
改变类的属性值 , 当改变类的属性值,所有对象都会同步改变
Python学员.eyes_num = 3
c1.eyes_num
>>3
c2.eyes_num
>>3
添加一个新的属性, 所有对象都会获得这个新的属性
Python学员.place = '内蒙古'
c1.place
>>'内蒙古'
c2.place
>>'内蒙古'
我们给某个对象的属性重新赋值, 则改变这个对象的该属性值,其他对象该属性不会发生变化
c1.place = '上海'
c1.place
>>'上海'
c2.place
>>'内蒙古'
三、类的方法
类的方法实际上就是封装在类中的函数, 类中的方法一定会具有一个参数, 这个参数就是该对象本身,
我们这里以self来代表目前调用这个方法的对象.
也就是说类的方法和函数的区别在于, 方法已经有了一个要操作的对象了, 而函数需要把操作的目标传入进去.
# 定义一个Python学员的类
class Python学员:
"""类功能: 用于记录所有Python学员"""
# 类属性: 将来用这个类实例化出的所有对象,都有的属性
eyes_num = 2 # 所有用这个类实例化的对象一定都有2只眼睛
hair_color = 'black'
# 给这个类添加功能, 学名: 叫做方法 method,(类里面定义的函数)
def listen_class(self): # 在函数里面定义的方法,都有一个默认的参数self
# self 指代的是我们将来要用这个类实例化的对象
return '这个人在听课'
c1 = Python学员()
c2 = Python学员()
c1.listen_class() # 方法必须加括号
>>'这个人在听课'
c2.listen_class()
>>'这个人在听课'
3.1 类的方法的参数
和函数相同, 类也可以具有参数, 参数在调用方法的时候传入即可.
class Python学员:
eyes_num = 2
hair_color = 'black'
def listen_class(self):
return '这个人在听课'
def sing_a_song(self , song_name):
return '这个人正在唱歌, 歌曲的名字叫做:{}'.format(song_name)
c1 = Python学员()
c2 = Python学员()
c1.sing_a_song('春天里')
>>'这个人正在唱歌, 歌曲的名字叫做:春天里'
c2.sing_a_song('小燕子')
>>'这个人正在唱歌, 歌曲的名字叫做:小燕子'
3.2 初始化方法
在类被实例化的时候, 有一个方法会被自动运行, 这个方法就是 __init__(self)
这个方法主要用于, 在一个对象被实例化的时候, 为它赋予一个属于自己的属性.
例如, Python学员姓名, 这个姓名我们不能用类属性进行保存, 因为每个学员的姓名是不同的.
这种针对于每个对象不同的变量我们叫做实例变量
# 定义一个Python学员的类
class Python学员:
eyes_num = 2
hair_color = 'black'
def __init__(self, name, age): # 参数,传入这个对象的对象属性
# 把传进来的参数, 赋值给这个对象
self.name = name
self.age = age
# 当实例化的时候, __init__ 这个特殊方法就会自动被运行
c1 = Python学员('令狐冲', 28)
c2 = Python学员('李寻欢', 42)
c1.name
>>'令狐冲'
c2.name
>>'李寻欢'
c1.age
>>28
c2.age
>>42
3.3 可以在方法中直接使用类属性和实例属性
class Python学员:
eyes_num = 2
hair_color = 'black'
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
return "大家好,我叫做{},我今年{}岁,我有{}只眼睛,我的头发是{}色的.".format(self.name,
self.age,self.eyes_num,self.hair_color)
c1 = Python学员('令狐冲', 28)
c2 = Python学员('李寻欢', 42)
c1.introduce()
>>'大家好,我叫做令狐冲,我今年28岁,我有2只眼睛,我的头发是black色的.'
3.4 类的方法参数写法
class Python学员:
eyes_num = 2
hair_color = 'black'
def __init__(self, name, age):
self.name = name
self.age = age
def listen_class(self , status): # 在函数里面定义的方法,都有一个默认的参数 self
# 状态编码: 0 : 这个人没有听课 1: 这个人假装在听课 2: 这个人在认真听课
if status == 0:
return "{}没有在听课".format(self.name)
elif status == 1:
return '{}在假装听课'.format(self.name)
else:
return '{}在认真听课'.format(self.name)
c1 = Python学员('令狐冲', 28)
c1.listen_class(0)
>>'令狐冲没有在听课'
四、练习
定义一个计算器Calculator的类
类属性:
产地(Place_of_Origin) = ‘made in China’
实例属性:
颜色(colour)
品牌(brand)
价格(price)
方法(技能):
sum(a, b)求两个数的和
summ(a, b, c, d,…)求一系列数的和
summ1(a, b, c, d,…)求一系列数的倒数和
额外添加一个方法: 计算器自我介绍功能: 介绍自己的产地,价格,品牌,颜色
最后实例化三个对象出来试试功能
class Calculator:
Place_of_Origin = 'made in China'
def __init__(self,colour,brand,price):
self.colour = colour
self.brand = brand
self.price = price
def sum(self,a,b):
return a+b
def summ(self,*args):
n = 0
for i in args:
n += i
return n
def summ1(self,*args):
n=0
for i in args:
n+= 1/i
return n
def introduce(self):
# 如果在不允许换行的地方换行, 需要加 \
return '我是一个可爱的{}的计算器,我是被{}创造出来的,\
你只需要花{}钱就可以获得我,我的产地是{}'.format(self.color,
self.brand,self.price,self.Place_of_Origin )
a1 = Calculator('蓝色','晨光',32)
a1.introduce()
>>'我是一个可爱的蓝色的计算器,我是被晨光创造出来的,你只需要花32钱就可以获得我,我的产地是made in China'
五、继承
抽象即抽取类似或者说比较像的部分。
抽象分成两个层次:
1.将奥巴马和梅西这俩对象比较像的部分抽取成类;
2.将人,猪,狗这三个类比较像的部分抽取成父类。
抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)
Python中继承的基本语法
class Classname(baseclasslist):
'''类的说明文档'''
statement # 类体
class 类名(父类):
类里面的代码
Classname:类名
baseclasslist:用于指定要继承的基类,可以有多个,类名之间用逗号分隔,如果不指定,将默认使用所有Python对象的根类object。
class Python学员:
'''说明:这是一个用于记录Python学员的类
参数说明:目前还没有参数'''
place = "内蒙古" # 所有的实例都有这个共同的属性
def __init__(self, name, age):# 这个name什么时候传呢? 实例化对象的时候传
self.name = name
self.age = age
def listen_class(self, status):
'''参数为学员的状态, status 为0 代表, 没有听课, 1代表正在听课, 2代表假装听课'''
if status == 0:
return '{}没有在听课'.format(self.name)
elif status == 1:
return '{}正在认真听课'.format(self.name)
elif status == 2:
return '{}假装在听课'.format(self.name)
def song(self, song_name):
return "这个人正在唱一首歌, 歌的名字叫做<{}>".format(song_name)
def introduce(self):
return "大家好, 我的名字是{}, 我今年{}岁, 我来自{}".format(self.name, self.age, self.place)
def sleep(self, status):
if status == 'yes':
return "{}正在睡觉".format(self.name)
elif status == 'no':
return "{}很清醒".format(self.name)
else:
return "{}正在半梦半醒之中".format(self.name)
class Python讲师:
'''说明:这是一个用于记录Python学员的类
参数说明:目前还没有参数'''
place = "内蒙古" # 所有的实例都有这个共同的属性
def __init__(self, name, age):# 这个name什么时候传呢? 实例化对象的时候传
self.name = name
self.age = age
def teacher_class(self, status):
'''参数为学员的状态, status 为3 代表都在听课, 4代表有人在听课 , 5代表都没有在听课'''
if status == 3:
return '{}上课中,大家都在听课'.format(self.name)
elif status == 4:
return "{}上课中, 有一部分人在听课".format(self.name)
elif status == 5:
return '{}上课中, 没有人在听课'.format(self.name)
def song(self, song_name):
return "这个人正在唱一首歌, 歌的名字叫做<{}>".format(song_name)
def introduce(self):
return "大家好, 我的名字是{}, 我今年{}岁, 我来自{}".format(self.name, self.age, self.place)
上面的两个类中, 有一部分功能是相同的
居然要把相同的功能写两遍, 换你你能忍吗? 不能忍, 那么怎么办呢? 用继承
class Python人:
"""上面两个类中共同的部分,放入到这个父类当中"""
place = "内蒙古" # 所有的实例都有这个共同的属性
feeling = '正常'
def __init__(self, name, age):# 这个name什么时候传呢? 实例化对象的时候传
self.name = name
self.age = age
def song(self, song_name):
return "这个人正在唱一首歌, 歌的名字叫做<{}>".format(song_name)
def introduce(self):
return "大家好, 我的名字是{}, 我今年{}岁, 我来自{}".format(self.name, self.age, self.place)
class Python学员(Python人):# 继承Python人类
# 我想给他添加一些新功能
def listen_class(self, status):
'''参数为学员的状态, status 为0 代表, 没有听课, 1代表正在听课, 2代表假装听课'''
if status == 0:
return '{}没有在听课'.format(self.name)
elif status == 1:
return '{}正在认真听课'.format(self.name)
elif status == 2:
return '{}假装在听课'.format(self.name)
class Python讲师(Python人):
def teacher_class(self, status):
'''参数为学员的状态, status 为3 代表都在听课, 4代表有人在听课 , 5代表都没有在听课'''
if status == 3:
return '{}上课中,大家都在听课'.format(self.name)
elif status == 4:
return "{}上课中, 有一部分人在听课".format(self.name)
elif status == 5:
return '{}上课中, 没有人在听课'.format(self.name)
注意:在子类里面吗如果有和父类名称相同的方法,那么子类的方法,会覆盖掉父类的方法
这样就实现了继承,减少了工作量而且功能与第一种方法是相通的