Python:面向对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QXNwvYBx-1595756490698)(F:\JianShu_material\Python\图片\面向对象\面向对象.png)]

1. 类与对象

1.1 类与对象的创建

  • 类名为驼峰式命名法,每个单词开头大写
  • 每个类都自动继承Object类
  • 类中的每个属性都必须有初始值,哪怕这个值是0或空字符串
  • 可以通过“类名.属性”的方式修改类的普通属性
# 类的创建
# 由于类的方法会在下面讲述,所以这里创建的类只有属性
class Person:
    name = 'Licy'
    age = '18'

# 对象的创建
person1 = Person()
person2 = Person()

# 同一类的不同对象的初始属性相同
print(person1.age) #18
print(person1.name) #Licy
print(person2.age) #18
print(person2.name) #Licy

# 可修改对象的属性,但类中属性不变
person1.age = 12
print(person1.age) #12

# 可修改类的属性,对象属性都发生改变
Person.age = 100
print(person2.age) #100

1.2 类的普通方法

  • 每个方法中形参self必不可少,还必须位于其他形参的前面,self代表当前对象
  • 可以在类的外面,通过对象添加其独有的属性,其余对象不能调用
  • 可以通过“对象名.方法名()”的方式调用类中的方法
  • 普通方法不能通过“类名.方法名()的方式调用”
  • 类中普通方法之间的相互调用要通过“self.方法名”的方式
class Phone:
    # 创建属性
    brand = "xiaomi"
    price = 4999

    def testSelf(self):
        print(self)

    def call(self):
        print("正在打电话")

    def color(self):
        print("颜色是",self.phoneColor)

# 创建类的对象
phone1 = Phone()
phone2 = Phone()

# self代表当前对象
print(phone1) #<__main__.Phone object at 0x000001F3140072C8>
phone1.testSelf() #<__main__.Phone object at 0x000001F3140072C8>

# 调用方法
phone1.call() #正在打电话
phone2.call() #正在打电话

# phone2不能调用color方法,因为phone2没有color属性
phone1.phoneColor = 'blue'
phone1.color() #正在打电话

1.3 构造器与__ init() __方法

  • __ init() __被称为类的构造器,也称为初始化方法,也属于魔术方法之一
  • 当创建类的实例时,Python就会自动调用__ init() __,这一方法动态地创建属性
  • __ init() __在使用参数情况下使同一类的不同对象具有不同相同属性
class Phone:
    def __init__(self,brand,price):
        self.brand = brand
        self.price = price

    def message(self):
        print(self.brand,self.price)

# 创建对象
phone1 = Phone("huawei",2999)
phone2 = Phone("xiaomi",2399)

# message()方法
phone1.message() #huawei 2999
phone2.message() #xiaomi 2399

# 修改属性
phone1.brand = "xiaomi"
phone1.message() #xiaomi 2999

1.4 类方法

  • 类方法通过装饰器“@classmethod”来修饰,属于类的方法,不依靠对象的存在而存在
  • 类方法的参数为固定参数为cls,代表当前类,cls不能调用非类属性,因为类不能调用非类属性
  • 可以通过“类名.类方法”的方式调用类方法,对象也可以调用类方法
  • 类方法中不能调用普通方法,因为类方法中不能使用self
class Phone:
    # 类属性
    a = 123

    def __init__(self,brand):
        self.brand = brand

    def call(self):
        print("正在打电话")

    @classmethod
    def test(cls):
        print("这是一个类方法",cls.a)

# 未创建对象,可以通过类名调用类方法
Phone.test()
# 未创建对象,可以通过类名调用类属性
print(Phone.a)

# 普通方法可以调用类方法
p1 = Phone("huawei")
p1.test()

1.5 静态方法

  • 静态方法通过装饰器“@staticmethod”来修饰,无固定参数

  • 静态方法与类方法及其相似,可调用的内容一致,但类方法是可通过cls和类名调用,静态方法只能用类名调用

1.6 魔术方法

魔术方法就是一个类/对象中的方法,和普通方法唯一的不同时,普通方法需要调用!而魔术方法是在特定时刻自动触发。

  • __ init __:

    初始化魔术方法
    触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)
    参数:至少有一个self,接收对象
    返回值:无
    作用:初始化对象的成员
    注意:使用该方式初始化的成员都是直接写入对象当中,类中无法具有其中的自创属性
    
  • __ new __:

    实例化魔术方法
    触发时机: 在实例化对时触发
    参数:至少一个cls 接收当前类
    返回值:必须返回一个对象实例
    作用:实例化对象,开辟内存空间给__init__
    注意:实例化对象是Object类底层实现,其他类继承了Object的__new__才能够实现实例化对象。
    没事别碰这个魔术方法,先触发__new__才会触发__init__ 
    
  • __ call __:

    调用对象的魔术方法
    触发时机:将对象当作函数调用时触发 对象()
    参数:至少一个self接收对象,其余根据调用时参数决定
    返回值:根据情况而定
    作用:可以将复杂的步骤进行合并操作,减少调用的步骤,方便使用
    注意:必须重写__call__方法才能将对象当作函数使用
    
  • __ del __:

    析构魔术方法
    触发时机:当对象没有用(没有任何变量引用该对象)的时候被触发
    参数:一个self 
    返回值:无
    作用:使用完对象是回收资源
    注意:del不一定会触发当前方法,只有当前对象没有任何变量接收时才会触发
    
  • __ str __:

    触发时机:使用print(对象名)或者str(对象名)的时候触发
    参数:一个self接收对象
    返回值:必须是字符串类型
    作用:print(对象名)时进行操作,得到字符串,通常用于快捷操作,而不再打印出对象地址
    注意:无
    

2. 私有化

2.1 私有化属性

在Python中,可以使用"__"添加在一变量之前,来表示对这一变量的私有化,具有以下特点

  • 私有化属性不能直接调用、修改
  • 私有化属性可以通过getXxx和setXxx来调用和修改
class Student:
    def __init__(self,name,age):
        self.__name = name
        self.__age = age

    def setAge(self,age):
        self.__age = age

    def getAge(self):
        return self.__age

s = Student("zhangsan",18)
# 不能直接调用私有属性,会报异常
# print(s.__age,s.__name)

# 可以通过getAge()方法调用Age
print(s.getAge()) #18

# 可以通过setAge()方法修改Age
s.setAge(100)
print(s.getAge()) #100

2.2 使用装饰器实现私有化

  • 可以使用装饰器"@property"来修饰函数以实现私有化
  • 可以使用装饰器"@同名函数名.setter"来修饰函数以实现修改属性
  • 用装饰器的方式实现私有化,调用与修改属性与为私有化之前相同
class Student:
    def __init__(self,name,age):
        self.__name = name
        self.__age = age

    @property
    def age(self):
        return self.__age

    # 同一类中不能有函数名不能相同,但使用构造器"@同名函数名.setter"可以实现同名函数
    @age.setter
    def age(self,age):
        self.__age = age

s = Student("zhangsan",18)

# 使用装饰器@property后,可以像为私有化之前"对象.属性"的方式调用对象
print(s.age) #18

# 修改属性值,和原来未私有化之前的方式相同
s.age = 100
print(s.age) #100

3. 继承

3.1 实现继承关系

  • 定义子类时,必须在括号内指定父类的名称。
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def run(self):
        print(self.name + " is running")

class Student(Person):
    pass

s = Student("Peter",18) 
s.run() #Peter is running

3.2 父类方法的重写

  • 重写后,也可以使用super关键字调用父类的方法
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def run(self):
        print("父类的跑步方法")


class Student(Person):
    def __init__(self,name,age,id):
        self.name = name
        self.age = age
        self.id = id

    def run(self):
        super().run()
        print("子类的跑步方法 ")

s = Student("Peter",18,12345)
s.run() 

3.3 多重继承

  • Python可以实现多继承
  • 若多继承中父类有同名的方法,可以使用魔术方法__ mro __来检查搜索顺序
class A:
    def test(self):
        print("--------AAA")

class B:
    def test(self):
        print("--------BBB")

class C(B,A):
    def func(self):
        super().test()

c = C()
c.test() #--------BBB
c.func() #--------BBB
# 检查搜索顺序
print(C.__mro__) #(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

4. 多态

4.1 多态的实现

  • 在Java中多态涉及的类必须具有继承关系,而在Python中多态的实现,可以不具备继承关系,所以Python没有真正意义上的多态
class Person:
    def show(self,pet): # pet即可接收Pet,也可接收Cat、Dog,也可接收Tigger
        if isinstance(pet,Pet): # 判断对象(pet)是否为类(Pet)以及是否为其子类
            print("{}的名字叫{}".format(pet.role,pet.nickname))
        else:
            print("这不能作为宠物!")

class Pet:
    pass

class Cat(Pet):
    role = "小猫"

    def __init__(self,nickname):
        self.nickname = nickname

class Dog(Pet):
    role = "小狗"

    def __init__(self,nickname):
        self.nickname = nickname

class Tiger:
    role = "老虎"

    def __init__(self,nickname):
        self.nickname = nickname

c = Cat("喵喵")
d = Dog("汪汪")
t = Tiger("吼吼")

p = Person()
p.show(c) #小猫的名字叫喵喵
p.show(d) #小狗的名字叫汪汪
p.show(t) #这不能作为宠物!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值