#第1章/lei.py
# 定义一个父类,如下:
class Cat( ):
def __init__(self, name, color ):
self.name = name
self.color = color
def run(self):
print("%s--在跑" %self.name)
# 子类在继承的时候,在定义类时,小括号()中为父类的名字,继承Cat类如下:
class TianyuanCat(Cat):
def setNewName(self, newName):
self.name = newName
print(self.name)
def eat(self):
print("%s--在吃"%self.name)
Xuanmao = TianyuanCat("玄猫", "黑色")
print('Xuanmao的名字为:%s' %Xuanmao.name)
print('Xuanmao的颜色为:%s' %Xuanmao.color)
Xuanmao.eat()
Xuanmao.setNewName('小黑')
Xuanmao的名字为:玄猫 Xuanmao的颜色为:黑色 玄猫--在吃 小黑
虽然子类TianyuanCat没有定义初始化方法和run方法,但是父类(Cat)有,所以在子类继承父类的时候这个方法就被继承了,所以只要创建TianyuanCat的对象,就默认执行了那个继承过来的init()方法了。
此外,还需要注意的是:
(1)类的私有的属性,不能通过对象直接访问,但是可以通过方法访问。
(2)私有的方法不能通过对象直接访问。
(3)私有的属性、方法不会被子类继承,也不能被访问。
(4)一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用。
代码如下:
#第1章/lei.py
class Animal():
def __init__(self, name='动物', color='白色'):
self.__name = name
self.color = color
def __test(self):
print(self.__name)
print(self.color)
def test(self):
print(self.__name)
print(self.color)
class Dog(Animal):
def dogTest1(self):
#print(self.__name) #不能访问到父类的私有属性
print(self.color)
def dogTest2(self):
#self.__test() #不能访问父类中的私有方法
self.test()
A = Animal()
#print(A.__name) #程序出现异常,不能访问私有属性
print(A.color)
#A.__test() #程序出现异常,不能访问私有方法
A.test()
print("------分割线-----")
D = Dog(name = "小花狗", color = "黄色")
D.dogTest1()
D.dogTest2()
白色 动物 白色 ------分割线----- 黄色 小花狗 黄色
所谓多继承,即子类有多个父类,并且具有它们的特征,如下图所示。 Python中的多继承代码如下:
#第1章/lei.py
# 定义一个父类
class A:
def printA(self):
print('----A----')
# 定义一个父类
class B:
def printB(self):
print('----B----')
# 定义一个子类,继承自A、B
class C(A,B):
def printC(self):
print('----C----')
obj_C = C()
obj_C.printA()
obj_C.printB()
obj_C.printC()
----A---- ----B---- ----C----
注意一点,如果在上面的多继承例子中,如果父类A和父类B中,有一个同名的方法,那么通过子类去调用的时候,调用先继承的父类方法。代码如下:
#第1章/lei.py
class base(object):
def test(self):
print('----base test----')
class A(base):
def test(self):
print('----A test----')
# 定义一个父类
class B(base):
def test(self):
print('----B test----')
# 定义一个子类,继承自A、B
class C(A,B):
pass
obj_C = C()
obj_C.test()
#输出:----B test----
----A test----
所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法,代码如下:
#第1章/lei.py
class Cat:
def sayHello(self):
print("miaomiao~~")
class Xuanmao(Cat):
def sayHello(self):
print("miao!~~!!!")
xiaohei = Xuanmao()
xiaohei.sayHello()
#输出:miao!~~!!!
miao!~~!!!
在类的继承里面super()方法是很常用的,它解决了子类调用父类方法的一些问题,例如,当父类多次被调用时只执行一次,优化了执行逻辑,下面我们来详细看一下。
当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时self参数需要显式传递,代码如下:
#第1章/lei.py
class Cat1:
def sayHello(self):
print("miaomiao~~")
class Xuanmao(Cat):
def sayHello(self):
# 调用父类方法事,直接使用父类名称进行调用
Cat1.sayHello(self)
xiaohei = Xuanmao()
xiaohei.sayHello()
#输出:miaomiao~~
miaomiao~~
当使用继承时,一个子类会继承父类的属性和方法。但如果直接在子类中通过父类的名称来调用父类的构造函数或方法,就会面临一些限制和问题:
父类名称修改:如果更改了父类的名称,那么所有子类中的相关代码也必须跟着更改。这在大型项目中,尤其是子类众多时,会导致维护成本显著增加。
多继承的复杂性:Python支持多继承,即一个子类可以有多个父类。在多继承的情况下,如果子类需要调用所有父类的方法,那么使用传统的方式就需要明确地重复每个父类的名称,这增加了代码的复杂性和冗余。
为了解决这些问题,Python提供了super()函数。如下示例所示
#第1章/lei.py
class Cat2321:
def sayHello(self):
print("miaomiao~~")
class Xuanmao(Cat):
def sayHello(self):
# 使用super()代替父类类名,即便类名改变,这里的super也不需要修改。
super().sayHello()
xiaohei = Xuanmao()
xiaohei.sayHello()
#输出:miaomiao~~
miaomiao~~
使用super()可以带来以下优势:
简化代码:super()允许你不必显式地引用父类,这使得代码更加简洁、易于理解和维护。
自动解析正确的方法:在多继承的情况下,super()知道应该调用哪个父类的方法,遵循所谓的方法解析顺序(MRO)。这减少了多继承时潜在的复杂性和错误。
动态继承:super()的动态特性意味着你不需要硬编码父类的名称,使得代码更加灵活。如果父类发生变化,子类的代码不需要修改。