python笔记(17)--初识面向对象和三大特性(封装/继承/多态)
内容目录
- 面向对象基本用法
- 好处和应用场景
- 面向对象的三大特性
内容详细
1.面向对象基本格式
# 定义类
class 类名:
def 方法名(self,name):
print(name)
return 123
def 方法名(self,name):
print(name)
return 123
def 方法名(self,name):
print(name)
return 123
# 调用类中的方法
# 1.创建该类的对象
obj = 类名()
# 2.通过对象调用方法
result = obj.方法名('alec')
print(result)
# 例子
# 定义一个类:Account
class Account:
# 方法
def login(self):
print('登录')
def logout(self,name,*args,**kwargs):
return name
# 调用类中的方法
# 1.创建对象
x = Account() # 创建了一个Account类的对象
# 2.使用对象调用类中的方法
x.login()
# 3.使用其中的函数也可以传值,不管有没有传参第一位必须是self
date = x.logout('alec')
print(date)
应用场景:遇到很多函数,需要给函数进行归类和划分。【统一名词:封装】
2.对象的作用
-
存储一些值,以后方便自己使用
-
调用时实例化对象,相当于创建了一个独立的内存
-
对象是同一个对象,但是内存中参数的值是相对独立存在的
-
class Person: def show(self): print(self.name) p1 = Person() p1.name = 'liyazhou' p1.show() #liyanzhou p2 = Person() p2.name = 'liyanan' p2.show() #liyanan
-
#示例:
class File:
def read(self):
with open(self.Path, mode='r', encoding='utf-8') as f:
data = f.read()
return data
def write(self, content):
with open(self.Path, mode='a', encoding='utf-8') as f:
f.write(content)
# # 实例化了一个File类的对象obj1
obj1 = File()
# # 在对象中写了一个xxxxx = 'test.log'
obj1.Path = "test.log"
# # 通过对象调用类中的read方法,read方法中的self就是obj。
# # obj1.read()
manager1 = obj1.read()
print(manager1)
# # 实例化了一个File类的对象
obj2 = File()
obj2.Path = "logss.txt"
manager2 = obj2.read()
print(manager2)
# # 调用写的方法
obj3 = File()
obj3.Path = "logss.txt"
obj3.write('alec255')
第三种方法:类里加__init__()
这种方法
- 将数据封装到对象,方便使用
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)
# 类 () 实例化对象,自动执行此类中的 __init__方法。
# 可以把参数写进 __init__方法中,调用实例化对象时传参
p1 = Person('李亚楠',22,'男')
p1.show()
p2 = Person('亚洲',20,'男')
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):
print(self.file_path)
def update(self):
print(self.file_path)
p1 = File('log.txt')
p1.read()
p2 = File('xxxxxx.txt')
p2.read()
# 1. 循环让用户输入:用户名/密码/邮箱。 输入完成后再进行数据打印。
# ########## 列表的写法
USER_LIST = []
while True:
user = input('请输入用户名:')
pwd = input('请输入密码:')
email = input('请输入邮箱:')
temp = {'username':user,'password':pwd,'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,pwd,email):
self.username = user
self.password = pwd
self.email = email
USER_LIST = [对象(用户/密码/邮箱),对象(用户/密码/邮箱),对象(用户/密码/邮箱)]
while True:
user = input('请输入用户名:')
pwd = input('请输入密码:')
email = input('请输入邮箱:')
p = Person(user,pwd,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 = pwd
self.email = email
def info(self):
return "我的名字:%s,密码:%s,邮箱%s" %(item.username,item.password,item.email,)
USER_LIST = [对象(用户/密码/邮箱),对象(用户/密码/邮箱),对象(用户/密码/邮箱)]
while True:
user = input('请输入用户名:')
pwd = input('请输入密码:')
email = input('请输入邮箱:')
p = Person(user,pwd,email)
USER_LIST.append(p)
for item in USER_LIST:
msg = item.info()
print(msg)
3.游戏开发小示例
4.继承
-
子类(派生类)与父类(基类):子类对象调用方法时优先用子类中的对象,如果没有就去父类中找
-
父类中的方法调用时无法去子类找
# 父类(基类) class Base: def f1(self): pass # 子类(派生类) class Foo(Base): def f2(self): pass # 创建了一个子类的对象 obj = Foo() # 执行对象.方法时,优先在自己的类中找,如果没有就去父类中找 obj.f2() obj.f1() # 创建一个父类对象 man = Base() # 父类执行对象.方法时,只能在自己的类中找,不能去子类中找 man.f1() man.f2() #执行这个时会报错,因为父类不能去子类找
-
问题:什么时候才能用到继承?
- 一般有三个或以上的类中会用到继承
- 多个类中如果有公共的方法功能,可以放到基类中避免重复编写
-
继承练习题:
# 示例一: class Base: def f1(self): print('base.f1') class Foo(Base): def f2(self): print('Foo.f2') obj = Foo() obj.f1() #base.f1 obj.f2() #Foo.f2 # 示例二: 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'
- 注意:
- self 到时是谁:哪个实例了你的实例化
- self 是哪个类创建的,就从此类开始找,自己没有就去找父类
- 注意:
-
多继承关系,从左往右找
-
多继承是python的特性,其他语言很少有(JAVA / PHP都没有多继承关系)
5.多态(多种形态/多种类型)(鸭子模型)
- 鸭子模型:**鸭子类型(英语:duck typing)是动态类型的一种风格。****在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定
def func(arg):
v = arg[-1] #此函数中arg可以传入任何值,但调用时只有str / list / dict / tuple / set这些有下标位
print(v)
面试题:什么是鸭子模型
对于一个函数而言,python对于参数的类型不会限制,那么传入参数时就可以是各种类型,在函数中如果有例如:arg.send方法,那么就是对于传入类型的一个限制(类型必须有send方法)
这就是鸭子模型,类似于上述的函数我们认为只要能呱呱叫的就是鸭子(只要有send方法,就是我们想要的类型)
总结:
1.面向对象的三大特性:封装 / 继承 / 多态
-
封装
# 把同一类的方法封装进一个类中 class File: def read(self): pass def write(self): pass
# 把一些数据封禁到对象中,方便以后获取 class Person: def __init__(self.name,age): self.name = name self.age = age P = Person('yanan',22)
-
继承
class Base: pass class Foo(Base): pass
- 多继承
- self到底是谁?
- self是由于哪个类创建,则找方法时就从它开始
-
多态
# 鸭子模型 def func(arg): # 多种类型可以传参,很多事物 arg.send() # 必须具有send方法,呱呱叫
2.格式和关键词
class 类:
def __init__(self,x):
self.x = x
def 方法(self,name):
print(self.x,name)
# 实例化一个类的对象
v1 = 类(666) #类加括号,自动执行其中__init__方法,并传参进去666
v1.方法('yanan')
三个词:
- 类
- 对象
- 方法
3.什么时候用面向对象?
- 函数(业务功能)比较多,可以使用面向对象来进行归类。
- 想要做数据封装。(对有限的数据进行封装)(创建字典存储数据时,优先使用面向对象)。