第七章.面向对象
7.1面向对象三大特性
-
封装
-
继承
-
多态
7.1.1封装(基本格式)
-
封装的两种方式 :
将数据封装到方法 / 将方法封装到类
class 类名:
def 方法名(self,要传入参数一,要传入参数二):
print(name)
return 123
def 方法名(self,要传入参数一,要传入参数二):
print(name)
return 123
def 方法名(self,要传入参数一,要传入参数二):
print(name)
rturn 123
obj = 类名() #创建该类的对象
result = obj.方法名(要传入参数一,要传入参数二) #通过对象调用方法
print(result)
-
应用场景
遇到很多函数,需要给函数进行归类和划分时
-
什么是封装思想
将同一类函数封装到同一py文件,方便以后调用
-
广义的封装 :类中的成员
-
狭义的封装 :私有成员
-
__名字
-
只能在类的内部使用,既不能在类的外部调用,也不能在子类中使用
-
_类名__名字
7.1.2 继承
class Base: #父类(基类) def f1(self): pass class Foo(base): #子类(派生类) def f2(self): pass obj = Foo() #创建了一个子类(派生类)的对象 obj.f2() #执行对象.方法时,优先在自己的类中找,如果没有就是父类中找。 obj.f1() obj = Base() # 创建了一个父类的对象 obj.f1()
-
什么时候用到继承?
多个类中如果有公共的方法,可以放到基类中避免重复编写。
-
继承关系中的查找方法的顺序:
-
注意self到底是谁
-
注意self是哪个类创建的,就从此类开始找,自己没有就找 父类(基类 或 超类)。
-
深度优先 广度优先
#例一:
class Base:
def f1(self):
print('base.txt')
class Foo(Base):
def f2(self):
print('Foo.txt')
obj = Foo()
obj.f1() #base.txt
obj.f2() #Foo.txt#例二:
class Base:
def f1(self):
print('base.f1')
class Foo(Base):
def f2(self):
self.f1()
print('foo.f2')
obj = Foo()
obj.f2() #'base.f1'
#'foo.f2'#例三:
class Base:
def f1(self):
print('base.f1')
class Foo(Base):
def f2(self):
self.f1()
print('foo.f2')
def f1(self):
print('foo.f1')
obj = Foo()
obj.f2() #foo.f1
#foo.f2#例四
class Base:
def f1(self):
self.f2()
print('base.f1')
def f2(self):
print('base.f2')
class Foo(Base):
def f2(self):
print('foo.f2')
obj = Foo()
obj.f1() #'foo.f2'
#'base.f1'#例五:
class TCPServer:
pass
class ThreadingMixIn:
pass
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
passv#例六:
class BaseServer:
def serve_forever(self, poll_interval=0.5):
self._handle_request_noblock()
def _handle_request_noblock(self):
self.process_request(request, client_address)
def process_request(self, request, client_address):
pass
class TCPServer(BaseServer):
pass
class ThreadingMixIn:
def process_request(self, request, client_address):
pass
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
pass
obj = ThreadingTCPServer()
obj.serve_forever()-
补充
-
#例一:
class StarkConfig(object):
pass
class AdminSite(object):
def __init__(self):
self.data_list = []
def register(self,arg):
self.data_list.append(arg)
site = AdminSite()
obj = StarkConfig()
site.register(obj) #[<__main__.StarkConfig object at 0x00000000025393C8>] 为列表里面是一个StarkConfig类
#例二:
class StarkConfig(object):
def __init__(self,name,age):
self.name = name
self.age = age
class AdminSite(object):
def __init__(self):
self.data_list = []
self.sk = None
def set_sk(self,arg):
self.sk = arg
site = AdminSite() # data_list = [] sk = []
site.set_sk(StarkConfig) #site.sk = StarkConfig
site.sk('alex',19)
#例三:
class StackConfig(object):
pass
class Foo(object):
pass
class Base(object):
pass
class AdminSite(object):
def __init__(self):
self._register = {}
def registry(self,key,arg):
self._register[key] = arg
site = AdminSite() #site._register = {}
site.registry(1,StackConfig) #{1:StackConfig}
site.registry(2,StackConfig) #{1:StackConfig,2:StackConfig}
site.registry(3,StackConfig) #{1:StackConfig,2:StackConfig,3:StackConfig}
site.registry(4,Foo) #{1:StackConfig,2:StackConfig,3:StackConfig,4:Foo}
site.registry(5,Base) #{1:StackConfig,2:StackConfig,3:StackConfig,4:Foo,5:Base}
for k,v in site._register.items():
print(k,v() ) # 1 StackConfig地址
# 2 StackConfig地址
# 3 StackConfig地址
# 4 Foo地址
# 5 Base地址
#例四;
class StackConfig(object):
pass
class UserConfig(StackConfig):
pass
class AdminSite(object):
def __init__(self):
self._register = {}
def registry(self,key,arg=StackConfig):
self._register[key] = arg
def run(self):
for key,value in self._register.items():
obj = value()
print(key,obj)
site = AdminSite() #site._register={}
site.registry(1) #{1:StackConfig}
site.registry(2,StackConfig) #{1:StackConfig,2:StackConfig}
site.registry(3,UserConfig) #{1:StackConfig,2:StackConfig,3:StackConfig}
site.run()
class StackConfig(object):
list_display = '李邵奇'
class UserConfig(StackConfig): #继承
list_display = '利奇航'
class AdminSite(object):
def __init__(self):
self._register = {}
def registry(self,key,arg=StackConfig):
self._register[key] = arg
def run(self):
for key,value in self._register.items():
obj = value()
print(key,obj.list_display)
site = AdminSite() #site._register = {}
site.registry(1) #{1:StackConfig}
site.registry(2,StackConfig) #{1:StackConfig,2:StackConfig}
site.registry(3,UserConfig) #{1:StackConfig,2:StackConfig,3:UserConfig}
site.run() #1 '李邵奇'
#2 '李邵奇'
#2 '利奇航'
class StackConfig(object):
list_display = '李邵奇'
def changelist_view(self):
print(self.list_display)
class UserConfig(StackConfig): #继承
list_display = '利奇航'
class AdminSite(object):
def __init__(self):
self._register = {}
def registry(self,key,arg=StackConfig):
self._register[key] = arg
def run(self):
for key,value in self._register.items():
obj = value()
obj.changelist_view()
site = AdminSite() #site._register = {}
site.registry(1) #{1:StackConfig}
site.registry(2,StackConfig) #{1:StackConfig,2:StackConfig}
site.registry(3,UserConfig) #{1:StackConfig,2:StackConfig,3:UserConfig}
site.run() #1 '李邵奇'
#2 '李邵奇'
#2 '利奇航'
7.1.3 多态
-
一个类表现出来的多种状态 --> 多个类表现出相似的状态
(多种形态/多种类型) 鸭子模型
#python
def func(arg):
v = arg[-1] # arg.append(9)
print(v)
# java
def func(str arg):
v = arg[-1]
print(v)
面试题:什么是鸭子模型。
对于一个函数而言,python对于参数的类型不会限制,那么传入参数时就可以是各种类型,在函数中如果有例如:arg.send方法,那么就是对于传入类型的一个限制(类型必须有send方法)。
这就是鸭子模型,类似于上述的函数我们认为只要能呱呱叫的就是鸭子(只要有send方法,就是我们想要的类型)
7.2对象的作用
对象的作用 : 存储一些值,方便以后自己调用
class File:
def read(self):
with open(self.xxxx,mode='r',encoding='utf-8') as f:
data = f.read()
return data
def write(self,content):
with open(self.xxxx,mode='a',encoding='utf-8') as f:
f.write(content)
obj1 = File() #实例化一个File类对象
obj1.xxxx = 'text.txt' #在对象中写了一个 xxxx = 'text.txt'
obj1.read() #通过对象调用类中的read方法,read方法中的self就是obj1
obj1.write('alex')
obj2 = File() #实例化一个File类对象
obj2.xxxx = 'info.txt' #在对象中写了一个 xxxx = 'text.txt'
obj2.read() #通过对象调用类中的read方法,read方法中的self就是obj1
obj2.write('alex')
class Person:
def show(self):
temp = '我是%s,年龄:%s,性别:%s' %(self.name,self.age,self.gender,)
print(temp)
p1 = Person() #实例化一个Person类对象
p1.name = '张三'
p1.age = '17'
p1.gender = '男' #传入三个参数
p1.show() #调用类中的show方法
p2 = Person() #实例化一个Person类对象
p2.name = '李四'
p2.age = '19'
p2.gender = '男' #传入三个参数
p2.show() #调用类中的show方法
#简化
class Person:
def __init__(self,n,a,g): #初始化方法(构造方法),给对象的内部做初始化
self.name = n
self.age = a
self.gender = g
def show(self):
temp = '我是%s,年龄:%s,性别:%s' %(self.name,self.age,self.gender,)
print(temp)
p1 = Person('张三','17','男') # 类() 实例化对象,自动执行此类中的 __init__方法。
p1.show()
p2 = Person('李四','19','19')
p2.show(
总结
-
如果写代码时,函数比较多比较乱,可以将函数归类并放到同一类中
-
函数如果有反复使用的公共值,就可以放到对象中.
class File:
def __init__(self,path):
self.file_path = path
def read(self): #读
print(self.file_path)
def write(self,content) #写
print(self.file_path)
def delete(self,content) #删
print(self.file_path)
def update(self) #更新
print(self.file_path)
p1 = File('log.txt')
p1.read()
p2 = File('xxxxxx.txt')
p2.read()
#例题:循环让用户输入:用户名/密码/邮箱,输入完成后进行数据打印
#法一:
USER_LIST = []
while True:
user = input('请输入用户名:')
psw = input('请输入密码:')
email = input('请输入邮箱:')
temp = {'username':user,'password':psw,'email':email}
USER_LIST.append(temp)
for item in USER_LIST:
temp = '用户名:%s,密码:%s,邮箱:%s' %(item['username'],item['password'],item['email'])
print(temp)
#法二:面向对象写法(一)
class Person:
def __init__(self,user,psw,email):
self.username = user
self.password = psw
self.email = email
USER_LIST = [] #添加之后变为[对象(用户/密码/邮箱),对象(用户/密码/邮箱),对象(用户/密码/邮箱)]
while True:
user = input('请输入用户名:')
psw = input('请输入密码:')
email = input('请输入邮箱:')
p = Person(user,psw,email)
USER_LIST.append(p)
for item in USER_LIST:
temp = '用户名:%s,密码:%s,邮箱:%s' %(item['username'],item['password'],item['email'])
print(temp)
#法三:面向对象写法(二)
class Person:
def __init__(self,user,pwd,email)
self.username = user
self.password = psw
self.email = email
def info(self): #因为有__init__(self,user,pwd,email),所以可以直接用
return '用户名:%s,密码:%s,邮箱:%s' %(item.username,item.password,item.email)
USER_LIST = [] #添加之后变为[对象(用户/密码/邮箱),对象(用户/密码/邮箱),对象(用户/密码/邮箱)]
while True:
user = input('请输入用户名:')
psw = input('请输入密码:')
email = input('请输入邮箱:')
p = Person(user,psw,email)
USER_LIST.append(p)
for item in USER_LIST:
temp = '用户名:%s,密码:%s,邮箱:%s' %(item['username'],item['password'],item['email'])
print(temp)
7.3 游戏开发
class Police: #创建一个警察类
def __init__(self,name):
self.name = name
self.hp = 1000
def tax(self): #类里面的方法一收税
msg = '%s去收税' %(self.name)
print(msg)
def fight(self): #类里面的方法二战斗
msg = "%s去战斗" %self.name
lsq = police("张三")
zzh = police("李四")
tyg = police("王五")
class Bandit:
def __init__(self,nickname):
self.nickname = nickname
self.hp = 1000
def murder(self,name)
msg = '%s谋杀了%s' %(self,nickname,name,)
lcj = Bandit('二蛋') #已经调用类
print(lcj.nickname)
lp = Bandit('二狗')
zsd = Bandit('狗蛋')
#1.二狗谋杀李四,二狗生命值-50,李四生命值-100
lp.murder(zzh.name)
lp.hp = lp.lp - 50
zzh.hp = zzh.hp -100
class Police:
def __init__(self,name)
self.name = name
self.hp = 10000
def dao(self,other):
msg = "%s个了%s一刀。" %(self.name,other.nickname)
self.hp = self.hp - 10
other.hp = other.hp - 50
print(msg)
def qiang(self):
msg = "%s去战了个斗。" %(self.name,)
def quan(self,other):
msg = "%s个了%s一全。" %(self.name,other.nickname)
self.hp = self.hp - 2
other.hp = other.hp - 10
print(msg)
class Bandit:
def __init__(self,nickname)
self.nickname = nickname