文章目录
一、继承的语法格式
称为类B继承类A,B类的对象可以使用A类的属性和方法
可以实现代码复用
class 类B(类A):
pass
一个最基本的继承和方法调用
# 定义父类Animal
class Animal(object):
def play(self):
print("Animal's play method execute!")
# 定义Dog类,继承Animal类
class Dog(Animal):
pass
dog = Dog()
# Animal's play method execute!
dog.play()
二、继承的分类
单继承,多继承,多层继承
三、子类重写父类的同名方法
# 定义父类Animal
class Animal(object):
def play(self):
print("Animal's play method execute!")
# 定义Dog类,继承Animal类
class Dog(Animal):
def play(self):
print("Dog's play method execute!")
animal = Animal()
# Animal's play method execute!
animal.play()
dog = Dog()
# Dog's play method execute!
dog.play()
四、子类调用父类的同名方法
# 定义父类Animal
class Animal(object):
def play(self):
print("Animal's play method execute!")
# 定义Dog类,继承Animal类
class Dog(Animal):
def play(self):
print("Dog's play method execute!")
# 在子类中调用父类的play方法
def executeAnimalPlay(self):
# 方法一:父类.方法名(self,其它参数)
# 使用类名.方法名()调用时,系统不会自动传递实参值self,需要手动传值,如果这里没有传入self参数,则会报错
Animal.play(self)
# 方法二:super(类A,self).方法名(参数),会调用当前类A父类的方法
super(Dog,self).play()
# 方法三:方法二的简写,super().方法名(参数)
super().play()
dog = Dog()
# Animal's play method execute!
dog.executeAnimalPlay()
五、继承中的__init__方法
# 继承中的__init__方法
class Animal(object):
def __init__(self,name):
self.name = name
def __str__(self):
return f"name={self.name}"
class Dog(Animal):
# 子类重写了父类的__init__方法,默认不再调用父类的__init__方法,需要手动调用父类的__init__方法
# 给对象添加从父类继承的属性
def __init__(self,name,age):
super().__init__(name)
self.age = age
def __str__(self):
return f"name={self.name},age={self.age}"
dog = Dog('zhangsan',10)
# name=zhangsan,age=10
print(dog)
六、多继承
# 多继承:如果一个类有两个以上父类,就把这种关系称为多继承
class A(object):
def fun1(self):
print("A's fun1 execute!")
def Afun(self):
print('Afun execute!')
class B(object):
def fun1(self):
print("B's fun1 execute!")
def Bfun(self):
print('Bfun execute!')
class C(A,B):
pass
c = C()
# Afun execute!
c.Afun()
# Bfun execute!
c.Bfun()
'''
两个父类中都有fun1()
子类对象调用的是在声明时第一个父类的方法
C(A,B):在声明时第一个父类是A,因此调用A中的fun1方法
'''
# A's fun1 execute!
c.fun1()
七、多继承中调用指定父类的方法
# 多继承中调用指定父类的方法
# 多继承:如果一个类有两个以上父类,就把这种关系称为多继承
class A(object):
def fun1(self):
print("A's fun1 execute!")
def Afun(self):
print('Afun execute!')
class B(object):
def fun1(self):
print("B's fun1 execute!")
def Bfun(self):
print('Bfun execute!')
class C(A,B):
def fun1(self):
print("C's fun1 execute!")
# 调用指定父类中的方法
# 根据顺序链,调用类A的fun1方法
# A's fun1 execute!
super(C, self).fun1()
# 根据顺序链,调用类B的fun1方法
# B's fun1 execute!
super(A, self).fun1()
pass
c = C()
# Afun execute!
c.Afun()
# Bfun execute!
c.Bfun()
# C's fun1 execute!
# A's fun1 execute!
# B's fun1 execute!
c.fun1()
# 类名.__mro__可以查看当前的继承顺序链,也就是同名方法的调用顺序(从左到右)
# (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
print(C.__mro__)
八、私有属性和私有方法
私有属性
# 私有属性和方法
'''
私有属性和方法
在属性和方法前加上两个下划线,该属性或方法变为私有
私有属性不能在类外访问,只能在类内访问
私有属性不能被继承
'''
class People(object):
def __init__(self):
'''
定义__age为私有属性,类外无法访问,不能被继承
python中私有的本质是修改属性的名字,在创建属性的时候,会自动修改属性名
在属性名前加上"_类名"前缀
比如这个属性实际上全名是:_People__age
'''
self.__age = 0
people = People()
# 代码报错
# print(people.__age)
# 通过__dict__可以查看对象具有的属性信息,类型是字典,字典的key是属性名,字典的value是属性值
# {'_People__age': 0}
print(people.__dict__)
# 注意:这里不是修改私有属性,而是定义了一个新的公有属性
people.__age = 100
# {'_People__age': 0, '__age': 100}
print(people.__dict__)
私有方法
# 私有方法
'''
私有方法:在方法前加上'__'
私有方法,不能在类外访问
作用:一般作为类内部的方法使用,不让外部调用的时候去定义
'''
class Dog(object):
def fun1(self):
print('fun1 execute!')
self.__fun2()
def __fun2(self):
print('fun2 execute!')
dog = Dog()
# fun1 execute!
# fun2 execute!
dog.fun1()
九、类属性
'''
实例对象:通过class关键字定义的类创建的对象,即通过类实例化的
实例对象定义的属性被称为实例属性,即通过self定义的属性都称为实例属性
类对象:通过class定义的,python解释器在创建类的时候自动创建的
类对象的作用:
1.可以通过类对象定义实例对象
2.类对象可以保存一些属性信息,称为类属性
类属性的定义:
在类内部,方法外部定义的属性就是类属性
'''
class Dog(object):
# 定义类属性
className = 'dog'
def __init__(self,name,age):
# 定义实例属性
self.name = name
self.age = age
dog = Dog('lisi',1)
# 打印dog对象具有的属性
# {'name': 'lisi', 'age': 1}
print(dog.__dict__)
# 类名.__dict__
# {'__module__': '__main__', 'className': 'dog', '__init__': <function Dog.__init__ at 0x000001C35EA5E5E0>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': None}
print(Dog.__dict__)
# 访问类属性
# dog
print(Dog.className)
# 修改类属性
Dog.className = 'Dog class'
# Dog class
print(Dog.className)
# 注意:如果不存在与实例属性名相同的类属性,则可以使用实例对象访问类属性的值
# 但如果重名,一定访问类属性
# Dog class
print(dog.className)
十、类方法,静态方法
类方法
'''
实例方法:类中默认的方法就是实例方法
实例方法的第一个参数为self,表示实例对象
类方法:使用@classmethod装饰的方法,称为类方法,第一个参数为cls,代表类对象自己
如果一个方法使用了实例属性,则该方法一定要定义为实例方法
在不需要使用实例属性的前提下,需要使用类属性,可以将这个方法定义为类方法
'''
class Dog(object):
className = 'dog'
def __init__(self,name,age):
self.name = name
self.age = age
# 定义类属性
@classmethod
# cls是类方法的默认形参,在调用的时候,不需要手动传递,python解释器会自动传递
def getClassName(cls):
return cls.className
dog = Dog('lisi',2)
# dog
print(Dog.getClassName())
静态方法
'''
静态方法:
使用@staticmethod装饰的方法,称为静态方法,对参数没有特殊要求
当不需要使用实例属性,也不需要使用类属性的时候,可以将该方法定义为静态方法
'''
class Dog(object):
className = 'dog'
def __init__(self,name,age):
self.name = name
self.age = age
# 定义静态方法
@staticmethod
def show():
print("the Dog class")
dog = Dog('lisi',2)
# 静态方法的调用
# 1.对象.方法名()
# the Dog class
dog.show()
# 2.类名.方法名()
# the Dog class
Dog.show()
十一、多态
'''
多态:
在需要使用父类对象的地方传入子类对象,得到不同的结果
实现步骤:
1.子类继承父类
2.子类重写父类的同名方法
3.定义一个共同的方法,参数为父类对象,在方法中调用子类和父类同名的方法
'''
class Animal(object):
def __init__(self,name):
self.name = name
def play(self):
print(f"(动物){self.name}在玩")
class Dog(Animal):
# 定义play方法
def play(self):
print(f"(狗){self.name}在玩")
# 定义公共方法
def doPlay(obj):
obj.play()
animal = Animal('zhangsan')
dog = Dog('zhangsan')
# (动物)zhangsan在玩
doPlay(animal)
# (狗)zhangsan在玩
doPlay(dog)