【Python(11)类的继承】

继承是类与类的一种关系,是一种子类与父类的关系,即爸爸与儿子,爸爸生个儿子,儿子继承爸爸的属性和方法。

一、继承的意义

面向对象的编程带来的主要好处之一是代码的重用,实现各种重用的方法之一是通过继承机制。继承完全可以理解成类之间的父类和子类型关系。

二、继承的应用场景

假如我需要定义几个类,而类与类之间有一些公共的属性和方法,这时我就可以把相同的属性和方法作为基类的成员,而特殊的方法及属性则在本类中定义。这样子类只需要继承基类(父类),子类就可以访问到基类(父类)的属性和方法了,它提高了代码的可扩展性和重用行。e.g.如:猫,狗 都属于动物,它们行为相似性高,都会叫,会吃,会喝,会拉,会撒娇。

三、Python 类的继承

示例:

class Animal(object):  #  python3中所有类都可以继承于object基类
   def __init__(self, name, age):
       self.name = name
       self.age = age

   def call(self):
       print(self.name, '会叫')

######
# 现在我们需要定义一个Cat 猫类继承于Animal,猫类比动物类多一个sex属性。 
######
class Cat(Animal):
   def __init__(self,name,age,sex):
       super(Cat, self).__init__(name,age)  # 不要忘记从Animal类引入属性
       self.sex=sex

if __name__ == '__main__':  # 单模块被引用时下面代码不会受影响,用于调试
   c = Cat('喵喵', 2, '男')  #  Cat继承了父类Animal的属性
   c.call()  # 输出 喵喵 会叫 ,Cat继承了父类Animal的方法 

注意: 一定要用 super(Cat, self).init(name,age) 去初始化父类,
否则,继承自 Animal的 Cat子类将没有 name和age两个属性。
函数super(Cat, self)将返回当前类继承的父类,即 Animal,然后调用__init__()方法,
注意self参数已在super()中传入,在__init__()中将隐式传递,不能再写出self。

四、Python 对子类方法的重构

上面例子中 Animal 的子类 Cat 继承了父类的属性和方法,但是我们猫类 Cat 有自己的叫声 ‘喵喵’ ,这时我们可以对父类的 Call() 方法进行重构。如下:

class Cat(Animal):
   def __init__(self, name, age, sex):
       super(Cat, self).__init__(name,age)
       self.sex = sex

   def call(self):
       print(self.name,'会“喵喵”叫')

if __name__ == '__main__':
   c = Cat('喵喵', 2, '男')
   c.call()  # 输出:喵喵 会“喵喵”叫

类方法的调用顺序,当我们在子类中重构父类的方法后,Cat子类的实例先会在自己的类 Cat 中查找该方法,当找不到该方法时才会去父类 Animal 中查找对应的方法。(同实例对象)

五、Python 子类和父类的关系
class Animal(object):
   pass

class Cat(Animal):
   pass

A= Animal()
C = Cat()

子类与父类的关系是 “is” 的关系,如上 Cat 继承于 Animal 类,我们可以说:



判断对象之间的关系,我们可以通过 isinstance (变量,类型) 来进行判断:

print('"A" IS Animal?', isinstance(A, Animal))
print('"A" IS Cat?', isinstance(A, Cat))
print('"C" IS Animal?', isinstance(C, Animal))
print('"C" IS Cat?', isinstance(C, Cat))

>>>
"A" IS Animal? True
"A" IS Cat? False
"C" IS Animal? True
"C" IS Cat? True

拓展: isinstance() 判断变量类型

3)isinstance 函数

六、Python 中多态

类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Animal 派生出 Cat和 Dog,并都写了一个 call() 方法,如下示例:

class Animal(object):  
   def __init__(self, name, age):
       self.name = name
       self.age = age
   def call(self):
       print(self.name, '会叫')

class Cat(Animal):
   def __init__(self, name, age, sex):
       super(Cat, self).__init__(name, age)
       self.sex = sex

   def call(self):
       print(self.name, '会“喵喵”叫')

class Dog(Animal):
   def __init__(self, name, age, sex):
       super(Dog, self).__init__(name, age)
       self.sex = sex
   def call(self):
       print(self.name, '会“汪汪”叫')
def do(all):
   all.call()

A = Animal('小黑',4)
C = Cat('喵喵', 2, '男')
D = Dog('旺财', 5, '女')

for x in (A,C,D):
   do(x)

小知识:多态

这种行为称为多态。也就是说,方法调用将作用在 all 的实际类型上。C 是 Cat 类型,它实际上拥有自己的 call() 方法以及从 Animal 继承的 call 方法,但调用 C .call() 总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。

传递给函数 do(all) 的参数 all 不一定是 Animal 或 Animal 的子类型。任何数据类型的实例都可以,只要它有一个 call() 的方法即可。其他类不继承于 Animal,具备 call 方法也可以使用 do 函数。这就是动态语言,动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eason DayDayUp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值