目录

Python面向对象(4)多态类方法和类属性

Python面向对象(4)多态类方法和类属性

学习目标

  • 面向对象的三大特性
  • 类属性和实例属性
  • 类方法和静态方法

面向对象三大特性

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

  • 封装
    • 将属性和方法书写到类里面的操作即为封装
    • 封装可以为属性和方法添加私有权限
  • 继承
    • 子类可以默认继承父类的所有属性和方法
    • 子类可以重写父类的属性和方法
  • 多态
    • 传入不同的对象,可以产生不同的结果

了解多态

多态指的是一类事物有多种形态,(一个抽象类可以有多个子类,因为多态的概念依赖于继承),python多态最好依赖于继承书写。

  • 定义:多态是一种使用对象的方式,子类重写父类的方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果
  • 好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化。
  • 实现步骤:
    • 定义父类提供公共方法。
    • 定义子类并重写父类方法。
    • 传递子类对象给调用者,可以看到不同子类执行效果不同。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Dog(object):
    def work(self):     # 父类提供统一的方法
        print("人类伙伴")

class ArmyDog(Dog):
    def work(self): #   重写父类的方法
        print("追击敌人")

class DrugDog(Dog):
    def work(self):
        print("追查毒品")

class Person(object):
    def work_with_dog(self, ob):
        ob.work()


dogA = ArmyDog()
dogB = DrugDog()
P = Person()

P.work_with_dog(dogA)        # 追击敌人
P.work_with_dog(dogB)        # 追查毒品

类属性和实例属性

实例属性__init__()中描述的是某个事物的特征,即对象的属性特征,每一个对象所特有的;

与之不同的类属性,是类所拥有的属性,是所有对象共有的特征。

设置访问类属性

  • 类属性是类对象所拥有的属性,它被该类创建的所有实例对象所共有
  • 类属性可以使用类对象实例对象访问。
1
2
3
4
5
6
7
8
class Dog(object):
    tooth = 10

wangwang = Dog()    # 实例化一个旺旺
wangcai = Dog()     # 实例化一个旺财
print(wangcai.tooth) # 使用实例对象访问
print(wangwang.tooth)   # 使用实例对象访问
print(Dog.tooth)        # 使用类对象访问

类属性的优点:

  • 记录的某项数据始终保持一致时,不发生变化,则定义类属性。
  • 而实例属性要求每个对象为其单独开辟一份内存空间来记录数据,而类属性为全类所共有,仅占用一份内存,更加节省内存空间

修改类属性

类属性只能通过类对象进行修改,不能通过实例对象进行修改,如果通过实例对象修改类属性,表示创建一个新的同名实例属性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Dog(object):
    tooth = 10

wangwang = Dog()    # 实例化一个旺旺
Dog.tooth = 100 # 通过类对象修改
print(wangwang.tooth)   # 使用实例对象访问 100
print(Dog.tooth)        # 使用类对象访问 100
wangwang.tooth = 99
print(wangwang.tooth)   # 使用实例对象访问新创建的实例属性 99
print(Dog.tooth)        # 使用类对象访问仍然为 100

类方法和静态方法

类方法

类方法的特点就是需要用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须时类对象,一般以cls为第一个参数。

什么时候需要使用类方法呢?

  • 当方法中**需要使用类对象(如访问私有类属性)**时,定义类方法
  • 类方法一般和类属性配合使用

类方法的特点:

  • 类方法一般可以被或者是实例调用,而实例方法只能被实例对象调用。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Dog(object):
    __tooth = 10 # 私有的类属性

    @classmethod    # 需要使用类属性了,我们用类方法
    def get_tooth(cls):	# cls为类对象
        return cls.__tooth # 使用类来访问私有的类属性
    def get_tooth_normal(self):
        return self.__tooth   # 类属性可以使用对象来调用

wangcai = Dog()
print(wangcai.get_tooth())  # 类方法可以使用对象来调用
print(wangcai.get_tooth_normal())   # 实例方法可以使用对象调用
print(Dog.get_tooth())  # 类方法也可以使用类来调用

静态方法

静态方法的特点:

  • 需要通过装饰器@staticmethod来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(即形参没有self/cls)
  • 静态方法也能够通过实例对象类对象去访问。

静态方法的使用场景:

  • 当方法中既不需要使用实例对象(实例对象,实例属性),也不需要使用类对象(如类属性,类方法)时,定义静态方法。
  • 静态方法不需要参数传递,有利于减少不必要的内存占用和性能消耗
1
2
3
4
5
6
7
8
class Dog(object):
    @staticmethod
    def show_name():
        print("一只狗")

Dog.show_name()  # 类对象调用静态方法 一只狗
dog1 = Dog()
dog1.show_name() # 实例对象调用 一只狗

总结

  • 面向对象有三大特性:封装、继承、多态;
    • 封装指的是把属性和方法定义到类里,把某些属性和方法定义为私有,就包装为一个类中,即封装,与其他类的属性和方法互不影响;
    • 继承是类和类之间的关系,一个类可以在不重写代码的情况下建立继承关系,子类具有和父类同样的属性和方法;
    • 多态指的是一般在子类继承父类的情况下,根据传入不同的对象结果受不同子类则有不同的影响。
  • 类属性值得是在类中直接设置出的,可以供实例对象和类对象访问的,修改则只能通过类对象修改,如果通过实例对象修改则新建一个实例属性。实例属性则根据对象不同占用不同的内存空间,只能通过实例对象访问和修改,因此使用类属性可以节省内存。
  • 类方法与实例方法不同的是,类方法需要使用@classmethod装饰器来定义,类方法可以通过实例对象和类对象访问,类方法的第一个参数为cls是供类对象传入的,而实例方法只能使用实例对象访问,且不同对象开辟不同的实例方法空间。
  • 静态方法使用@staticmethod来定义,调用通过类对象和实例对象均可,减少不必要参数传递导致的内存消耗。