# -*- encoding: utf-8 -*-
"""
面向对象之多态
1、多态:一类事物有多种形态(最好依赖于继承,但不必须)
1.1、定义:多态是一种使用对象的方式,子类重写父类中的方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果。
1.2、优点:调用灵活,更容易编写出通用的代码
2、类属性和实例属性
2.1、类属性:类对象拥有的属性,被该类所有实例对象所共有
2.1.1、使用场景:记录某项指标,如果数据始终保持一致使用类属性
2.1.2、优点:仅占一份内存,更加节省内存空间
2.2.3、访问:可以通过 类对象 或者 实例对象 访问
类对象.类属性
实例对象.类属性
2.2.4、修改:只能通过类对象修改,不能通过实例对象修改。
若通过实例对象修改类属性,实则表示创建了一个实例属性。
2.2、实例属性:每个实例对象的同一实例属性不同
2.2.1、访问:仅能通过实例对象访问,不能通过类对象访问
2.2.2、缺点:实例属性要求每个对象为其单独开辟一份内存空间来记录数据。
即不同实例对象的实例属性各占一份内存空间。
3、类方法和静态方法
3.1、类方法:
3.1.1、特点:被修饰器@classmethod修饰,第一个参数必须是类对象,一般以cls作为第一个参数
3.1.2、使用场景:类方法一般与类属性配合使用
当方法中需要访问类对象(如需要访问私有属性)时,定义类方法
3.2、静态方法:
3.2.1、特点:被修饰器@staticmethod修饰,既不需要传入类对象,也不需要传入实例对象
(形参没有self/cls)
3.2.2、使用场景:取消不必要的参数传递,减少不必要的内存占用和性能消耗
4、类方法、静态方法、实例方法三者的区别
4.1、调用:类方法和静态方法能被类对象和实例对象直接调用;实例方法可以被实例对象调用,但是不能被类对象调用
4.2、结果:实例方法随着实例属性的变化而变化;
类方法中都是类属性,始终不变
静态方法中可以通过类对象.类属性访问类属性
"""
'''
(一)多态实现步骤
1、定义父类,提供公共方法
2、定义子类,重写父类方法
3、传递子类对象给调用者,可以看到不同子类对象,执行效果不同
'''
# 定义父类Dog
class Dog(object):
def work(self):
print('指哪打哪')
# 定义子类TrackerDog,重写父类Dog中的work方法
class TrackerDog(Dog):
def work(self):
print('追击犯人!')
# 定义子类DrugDog,重写父类Dog中的work方法
class DrugDog(Dog):
def work(self):
print('追击毒品!')
class Human(object):
# 传入对象dog,对象不同,执行的work函数不同
def work(self,dog):
dog.work()
td = TrackerDog()
dd = DrugDog()
zhangsan = Human()
# 传入不同的对象 td/dd,得到不同的结果
zhangsan.work(td) # 追击犯人!
zhangsan.work(dd) # 追击毒品!
# (二)、类属性和实例属性
# 1、类属性
class Dog(object):
# 定义类属性
tooth = 10
# 创建实例对象
d1 = Dog()
d2 = Dog()
# 通过类对象访问类属性
print(Dog.tooth) # 10
# 通过实例对象访问类属性
print(d1.tooth) # 10
print(d2.tooth) # 10
# 类对象拥有的属性,被该类所有实例对象所共有
# ***通过类对象修改类属性***
Dog.tooth = 20
# 通过类对象访问类属性
print(Dog.tooth) # 20
# 通过实例对象访问类属性
print(d1.tooth) # 20
print(d2.tooth) # 20
# ***通过实例对象修改类属性***
d1.tooth = 8
# 通过类对象访问类属性
print(Dog.tooth) # 20
# 通过实例对象访问类属性
print(d1.tooth) # 8
print(d2.tooth) # 20
# ***可以看出并不能通过实例对象来修改类属性!!!只是实例对象为自己创造了一个与类属性同名的实例属性!!!
# 2、实例属性
class Dog(object):
def __init__(self):
# 定义实例属性
self.age = 6
# 定义实例方法
def print_age(self):
print(f'狗子今年{age}岁')
d1 = Dog()
# 通过实例对象访问实例属性
print(d1.age) # 6
# 通过类对象访问实例属性
# print(Dog.age) # AttributeError: type object 'Dog' has no attribute 'age'
# (三)、类方法和静态方法
class Dog(object):
__age = 11
# 定义类方法
@ classmethod
def get_info(cls):
# cls 指代Dog类对象
return cls.__age
# 定义静态方法
@staticmethod
def print_info():
print('这是一只静态狗')
print(Dog.__age)
# 定义实例方法
def run(self):
print('狗会跑')
d1 = Dog()
# 类方法可以被实例对象调用
print(d1.get_info()) # 11
# 类方法可以被类对象调用
print(Dog.get_info()) # 11
# 静态方法可以被实例对象调用
print(d1.print_info()) # 这是一只静态狗 # 11
# 静态方法可以被类对象调用
print(Dog.print_info()) # 这是一只静态狗 # 11
# 实例方法可以被实例对象调用
print(d1.run()) # 狗会跑
# 实例方法不可以被类对象直接调用,需要在调用时传入实例对象
# print(Dog.run()) # TypeError: run() missing 1 required positional argument: 'self'
print(Dog.run(d1)) # 狗会跑
python基础学习20_面向对象之【多态】(包含多态、类属性与实例属性、类方法与实例方法)
最新推荐文章于 2024-07-29 20:49:38 发布