Python学习笔记(六)面向对象编程

最近准备HCIE的考试,用空余时间高强度学习python

介绍了Python中面向对象编程的基本概念,包括类、类的属性、类的方法、类的方法中实例方法、类方法、静态方法,在类与对象中动态添加属性和方法,以及继承、类变量、多态等概念

类(类对象):为了做区分而创建的一些特性的群体
子类:通过继承创建,为了在类下做更清晰的区分
对象:建立在类的基础上,在某一类或子类下的个体
实例:约等于对象,xx对象是xx类的实例化

在python中,一切都是对象;凡是对象,都是某个类的实例
使用面向对象编程,在做好细分之后,能够更快实现功能,更容易维护 类越细分,对象就越精细

类1 → 对象1,对象2

子类1 → 对象1,对象2
子类2...
子类3...

面向对象有三大特征:封装、继承、多态

类、类的属性、类的方法

#创建类————使用class关键字
#class 类名() 括号代表要继承,在规范上,类名的首字母要大写
class Ws:
    pass
class Xhy:
    pass

#创建对象——根据类创建一个属于这个类的对象
v1 = Ws() #v1是由Ws这个类实例化生成的对象,v1这个对象是Ws类的实例
v2 = Ws()
v3 = Ws()

#类————管理员、用户
#类的属性————是类里的变量。反映该类对象的信息,例如账号、密码、名字等
#类的方法————是类里的函数。反映该类对象能做的事,例如账号权限、添加用户、修改密码等,是一种方法,比如list.append,是自己定义的函数

#添加类的属性,一般都是类的可变属性
#添加一个不变的属性
class User_info: #通过__init__构造方法
    def __init__(self):  #self代表要被实例化的对象
        self.username = 'ws'  #为其赋值
        self.age = '24'
        self.password = 'ws111'
user1 = User_info()
print(user1.password)
#ws111
#添加类的可变属性,这样可以适用更多user
class User_info:
    def __init__(self,username,age,password):
        self.username = username
        self.age = age
        self.password = password

user1 = User_info('ws',24,'ws111')
user2 = User_info('xhy',23,'xhy111')
print(user1.username)
print(user2.password)
#ws
#xhy111

#添加类的方法,在创建了对象之后,就可以直接使用类的方法
class User_info:
    def __init__(self,name,password,age):
        self.name = name
        self.password = password
        self.age = age
    def show(self):
        print(self.name, self.password)
    def show_age(self):
        print(self.age)
user1 = User_info('ws','ws111',age=24)
user1.show()
#ws ws111
user1.show_age()
#24
#在方法中定义的类的属性,可以在全局进行调用
class User_info:
    def __init__(self,name):
        self.name = name
		def show_age(self):
		    self.age = 24  ####在方法中定义类的属性
		    print(self.age)
user1.show_age()
#24

实例方法、类方法、静态方法

#实例方法————首个参数为self的方法,绑定给该类的实例调用,类本身不能调用
class User_info:
    def __init__(self,name):
        self.name = name
    def show(self):
        pass
user1 = User_info('ws') #在实例方法中,必须要创建一个实例,才能使用类中的方法
user1.show()
#无法用类来直接调用,像User_info.show这样的用法

#类方法————首个参数为cls,并且以classmethod装饰的方法
#可以直接使用类来调用如User_info.show,但无法调用类的参数
class User_info:
    def __init__(self,name):
        self.name = name
    @classmethod
    def show(cls):
        print('ws')
    @classmethod
    def show_name(cls):
        print(self.name)
User_info.show()
#ws
User_info.show_name()
#报错,无法调用类的参数
#如果需要则需要额外在类方法中传入参数
class User_info:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    @classmethod #类方法的装饰器
    def show_name(cls, age):
        print(age)
User_info.show_name(24)
#24

#静态方法————不需要cls或self,使用staticmethod装饰,可以直接调用,但无法使用类的属性
class User_info:
    def __init__(self, name):
        self.name = name
    @staticmethod
    def show_name(): #需要传参则定义形参
        print('11111')
User_info.show_name()
#11111

面向对象的动态特性

动态添加属性、修改属性

#动态的添加对象和类的属性
# 添加到对象只会影响对象本身,而为类添加的属性会应用给所有对象
class User_info:
    def __init__(self, name):
        self.name = name
        self.username = 'ws' #添加一个固定的类的属性值
if __name__ == '__main__':
    user1 = User_info('ws') #创建了一个实例/对象user1
    user1.age = 24          #age这个属性只属于user1这个对象中,而不属于User_info的类
    print(user1.age)
    #24
    user1.age = 25          #动态修改对象的属性值
    print(user1.age)
    # 25
    User_info.password = 'ws111' #为类添加属性,如果没有会添加到user1中,且值是可修改
    print(user1.password)
    #ws111
    User_info.password = 'xhy111' #为类添加属性,如果原本有值就会修改
    print(user1.password)
    #xhy111
    User_info.username= 'xhy' #无法动态修改类中原本就有的属性值,实例化后的对象继承了类的值,不会变化
    print(user1.username)
    #ws

动态添加方法

添加实例方法、添加类方法、添加静态方法

#添加实例方法————只能单独为对象添加,不能为类添加
import types        #导入types模块
class User_info:
    pass
def show(self):     #准备一个实例方法
    print('111')
if __name__ == '__main__':
    user1 = User_info() #实例化一个对象
    #目标实例的方法 = types.MethodType(待添加函数名,目标函数名)
    user1.show = types.MethodType(show,user1)
    user1.show()
    #111

#添加类方法———只能为类添加
class User_info:
    pass
@classmethod
def show(cls):
    print('111')
if __name__ == '__main__':
    User_info.show = show #直接赋值就行,不要调用
    User_info.show()
    #111

#添加静态方法————只能为类添加
class User_info:
    pass
@staticmethod
def show():
    print('111')
if __name__ == '__main__':
    User_info.show = show
    User_info.show()
    #111

继承

子类继承父类之后可以直接使用父类定义好的属性和方法

#最简单的继承性质说明
class User():
    def __init__(self,name):
        self.name = name
    def show(self):
        print('111')
#class 子类名(父类名)
class U001(User):
    def age(self): #可以在子类里定义新的方法,只属于这个子类可用的
        print('123')
    def show(self):  #可以在子类里重写父类的方法,会盖掉父类的方法
        print('222')
if __name__ == '__main__':
    user1 = U001('ws')
    user1.show()
    #222

#super函数————调用父类的 方法

#继承父类方法————可以在子类的方法中调用父类的任意方法
class User:
    def __init__(self):
        self.age = 24
    def show(self,name):
        print(f'{self.age}岁,{name},是学生') #调用age
class U01(User):
    def __init__(self):
        self.age = 26
    def show2(self):
        print('222')        #多加一行显示区别
        super().show('ws')  #调用了父类中的方法show,并且原函数需要传参,所以这里也传参
if __name__ == '__main__':
    user1 = U01()
    user1.show2()           #调用的类的属性26岁是本类的属性,而不是父类的属性24岁
    #222
    #26岁,ws,是学生

#继承父类属性————分多种情况
1、全部保留属性,不新增
2、全部替换,只用自己的
3、保留部分属性,不新增
4、保留部分属性,有新增

#全部保留属性,不新增
class User_info:
    def __init__(self, username, password, email):
        self.username = username
        self.password = password
        self.email = email
class User(User_info):
    pass        #最简单,直接什么都不用动,不重写则全部保留

if __name__ == '__main__':
    user1 = User('ws','ws111','1320')
    print(user1.username)
    #ws

#全部替换,只用自己的
class User_info:
    def __init__(self, username, password, email):
        self.username = username
        self.password = password
        self.email = email
class User(User_info): 
    def __init__(self,age,job): #重写构造函数
        self.age = age
        self.job = job

if __name__ == '__main__':
    user1 = User('ws','ws111')
    print(user1.age)
    #ws
    print(user1.username)
    # 报错

#保留部分属性,不新增
class User_info:
    def __init__(self, username, password, email):
        self.username = username
        self.password = password
        self.email = email
class User(User_info):
    def __init__(self,username,password):
        # 使用super,重跑一遍父类构造函数的形参,并且只赋值自己要的,不要的空着
        super().__init__(username=username,password=password,email=None)
        #这样就只传了name和password两个属性
if __name__ == '__main__':
    user1 = User('ws','ws111')
    print(user1.username)
    #ws

#保留部分属性,有新增
class User_info:
    def __init__(self, username, password, email):
        self.username = username
        self.password = password
        self.email = email
class User(User_info):
    def __init__(self,username,password,job):
        self.job = job  #新增一个job属性
        super().__init__(username=username,password=password,email=None)
if __name__ == '__main__':
    user1 = User('ws','ws111','student')
    print(user1.username,user1.job)
    #ws student

类变量

在类中设置的变量,但不是类的属性

先介绍python中使用的查找算法

#Python的查找算法(包括变量的查找、类变量的查找、super函数调用)
#原则是自下而上,从里到外

#变量的查找
def fun():
    v1 = 0
    def fun1():
        v1 = 1       #先找最里层,即fun1中的v1
        print(v1)
if __name__ == '__main__':
    v1 = 2
    fun()
    #1
#super函数的调用
class fun:
    def show(self):
        pass
class fun1(fun):
    pass
class fun2(fun1)
    def show2(self):
        super().show() #这条super的对函数的调用首先会在fun1中寻找,然后去fun中寻找
if __name__ == '__main__':
    pass

#mro查找算法——应对多继承的情况下的查找
#应用于一个类继承了多个类的情况
#mro采用的算制为C3,融合了DFS(深度查询)和BFS(广度查询)
class fun():
    pass
class fun1():
    pass
class fun2(fun,fun1):
    pass
if __name__ == '__main__':
    v1 = fun2()
    print(v1.var)  #DFS按顺序,首先查找fun以及fun的父类,再查询fun1以及fun1的父类

#类变量
#类变量可以使用类来访问和修改
class User_info():
    v1 = 0
    def __init__(self,name):
        self.name = name
if __name__ == '__main__':
    user1 = User_info('ws')
    User_info.v1 = 1 #只使用类来访问和修改
    print(User_info.v1)
    #1
    #如果user1中没有v1的变量,则去user1的父类User_info中找v1
    print(user1.v1)
    #1
    user1.v1 = 2     #为对象动态添加了一个属性
    print(user1.v1)  #优先使用user1的v1
    #2
    print(User_info.v1)
    #1

多态

用来控制对象的行为

不同的对象调用同一个方法,表现出不同的状态

#多态需要有继承,只发生在父类和子类之间,需要有重写
#仅需一个函数,传递不同的对象,就能使用不同子类中的制定函数
#可扩展性和可维护性都增加了
class Version:
    def what(self):
        print('Version')
class V1(Version):
    def what(self):
        print('v1')
class V2(Version):
    def what(self):
        print('v2')
class V3(Version):
    def what(self):
        print('v3')
def fun(object):
    object.what()
if __name__ == '__main__':
    v1 = V1()
    v2 = V2()
    v3 = V3()
    fun(v1)
    fun(v2)
    fun(v3)
#v1
#v2
#v3

你可能感兴趣的:(Python,python,学习)