一、多态
含义:指同一种行为具有不同的表现形式
一个对象具有多种形态,在不同的使用环境中以不同的形态展示其功能,那我们就称该对象具有多态特征
eg:+ 号在不同的使用环境中,有着不同的功能
print(10+10) # 算术运算符:可以实现整型之间的相加操作
print('10'+'10') # 字符串拼接:实现字符串之间的拼接操作
1.1 多态的前提
前提:
1、继承
2、重写
多态的特点:
1. 不关注对象的类型,关注对象具有的行为,也就是对象的实例方法是否同名
2. 多态的好处可以增加代码的外部调用灵活度,让代码更加通用,兼容性比较强
3. 不同的子类对象,调用相同的父类方法,会产生不同的执行结果
eg:在子类中,同一种方法shout,有不同的表现形式
class Animal(object):"""父类:动物类"""def shout(self):print("动物会叫")
class Cat(Animal):"""子类一:猫类"""def shout(self):print("小猫喵喵喵")
class Dog(Animal):"""子类二:狗类"""def shout(self):print("小狗汪汪汪")
cat = Cat()
cat.shout()
dog = Dog()
dog.shout()
# 输出内容:
# 小猫喵喵喵
# 小狗汪汪汪
1.2 多态性
多态性:一种调用方法,不同的执行结果
eg:test 函数传入不同的对象,执行不同对象的eat方法
class Animal(object):def eat(self):print("我会干饭")
class Pig(Animal):def eat(self):print("猪吃猪饲料")
class Dog(Animal):def eat(self):print("狗吃狗粮")
# 多态性:定义一个统一的接口,一个接口多种实现
def test(obj): # 形参objobj.eat()
animal = Animal()
pig = Pig()
dog = Dog()
test(animal)
test(pig)
test(dog)
# 输出内容:
# 我会干饭
# 猪吃猪饲料
# 狗吃狗粮
二、静态方法
使用@staticmethod 来进行修饰,静态方法没有self、cls(后面会讲到)参数的限制
注意:静态方法与类无关,可以被转换成函数使用
在静态方法中,取消了不必要的参数传递,有利于减少不必要的内存占用和性能消耗
2.1 基本格式
定义格式:
class 类名:@staticmethoddef 方法名(形参):方法体
调用格式:
类名.方法名(实参)
对象名.方法名(实参)
2.2 静态方法实例
eg1:静态方法既可以使用对象访问,也可以使用类访问
class Person(object):@staticmethod # 静态方法def study():print("人类会学习")
# 静态方法既可以使用对象访问,也可以使用类访问
Person.study() # 输出:人类会学习
pe = Person()
pe.study() # 输出:人类会学习
eg2:静态方法中也可以传参
class Person(object):@staticmethod # 静态方法def study(name):print(f"{name}会学习")
Person.study('junjun') # 输出:junjun会学习
pe = Person()
pe.study('junjun') # 输出:junjun会学习,调用方法时传参数
三、类方法
使用装饰器@classmethod 来标识为类方法,对于类方法,第一个参数必须是类对象,一般是以cls作为第一个参数
注意:
1、当方法中需要使用到类对象(如访问私有类属性等),定义类方法
2、类方法一般是配合类属性使用
定义格式:
class 类名:@classmethoddef 方法名(cls,形参):方法体
eg:类方法内部可以访问类属性,或者调用其他的类方法
class Person(object):name = "junjun"@classmethoddef sleep(cls):print("cls",cls) # cls代表类对象本身,类本质上就是一个对象print("人类在睡觉")print(cls.name)
print(Person)
Person.sleep()
# 输出结果:
# <class '__main__.Person'>
# cls <class '__main__.Person'>
# 人类在睡觉
# junjun
四、总结
在类里面定义方法有三种:实例方法、静态方法、类方法
1.实例方法:方法内部访问实例属性,方法内部可以通过类名.类属性名来访问类属性
2.静态方法@staticmethod:方法内部,不需要访问实例属性和类属性,如果要访问类属性,通过类名.类属性名访问,不能访问实例属性
3.类方法@classmethod:方法内部只需要访问类属性,可以通过cls.类属性名访问类属性,不能访问实例属性
实例方法:
实例方法是绑定到类的实例上的方法。它们必须通过类的实例来调用,并且它们的第一个参数通常是self,指向调用该方法的实例本身。
eg:
class MyClass: def instance_method(self): print(f"这是一个实例方法,调用者是:{self}") # 创建类的实例
obj = MyClass()
# 调用实例方法
obj.instance_method() # 输出:这是一个实例方法,调用者是:<__main__.MyClass object at 0x...>
静态方法:
静态方法不依赖于类或实例,它们既不接收self也不接收cls作为第一个参数。它们通常用于在逻辑上属于类但不需要访问或修改类或实例状态的函数。静态方法使用@staticmethod装饰器来定义。
eg:
class MyClass: @staticmethod def static_method(): print("这是一个静态方法,不依赖于类或实例") # 直接通过类调用静态方法
MyClass.static_method() # 输出:这是一个静态方法,不依赖于类或实例
# 也可以通过实例调用静态方法,但这不是必需的
obj = MyClass()
obj.static_method() # 输出同上
类方法:
类方法绑定到类本身而不是类的实例。它们接收cls作为第一个参数,cls指向调用该方法的类本身。类方法使用@classmethod装饰器来定义,常用于创建或修改类级别的变量或执行类级别的操作。
eg:
class MyClass: class_variable = 0 @classmethod def class_method(cls): print(f"这是一个类方法,调用者是:{cls}") cls.class_variable += 1 print(f"类变量现在的值是:{cls.class_variable}") # 通过类调用类方法
MyClass.class_method() # 输出:这是一个类方法,调用者是:<class '__main__.MyClass'> 类变量现在的值是:1
# 通过实例调用类方法,虽然不推荐,但也可以
obj = MyClass()
obj.class_method() # 输出:这是一个类方法,调用者是:<class '__main__.MyClass'> 类变量现在的值是:2
联系:
1、所有的方法都可以访问类级别的属性(即类变量)
2、所有的方法都可以通过类名或实例名来调用(尽管对于实例方法和类方法,通过类名调用时需要传递实例或类本身作为第一个参数)
3、实例方法可以直接访问和修改实例属性,而静态方法和类方法则不能直接访问实例属性(除非通过其他方式传入)。
区别:
实例方法:第一个参数是self,必须通过实例调用
静态方法:无self或cls参数,可以通过类或实例调用,不依赖于类或实例
类方法:第一个参数是cls,代表类本身,可以通过类或实例调用
今天的分享就到这里了,希望能帮助到大家~