python类的继承重构_Python 类的继承

OOP主要好处之一是代码的重用,其一是通过继承。

继承:继承是base class类与subclass的父&子类的关系,儿子会继承爸爸的属性和方法。

Eg:

动物类为父类, 是所有动物的基类;猫类继承于动物类,是动物类的子类和派生类。

继承有单继承与多继承。 单继承即子类继承于一个类,多继承即子类继承于多个类。

继承使用场合:假如我要定义几个类,而类与类之间有一些公共的属性和方法,这时就可以把相同的属性和方法定义在基类中;各个实例独有的方法和属性在实例化后的本类中定义。这样子类只需要继承基类(父类),子类就可以访问基类的属性和方法了。

一、Python类的继承

定义一个Animal为基类.

class Animal(object): # 基本所有类都继承于object基类

def __init__(self, name, age):# 实例属性name和age,一个method叫cal

self.name = name

self.age = age

def call(self):

print(self.name, 'Meow')

class Cat(Animal): # 定义一个Cat类继承于Animal类,Cat类比Animal类多一个sex属性。

def __init__(self,name,age,sex):

super(Cat, self).__init__(name,age) # 记得从Animal类引入name和age属性

self.sex=sex

if __name__ == '__main__': # 单模块被引用时下面代码不会受影响,用于调试

c = Cat('Kitty', 2, 'male') # Cat类继承了父类Animal的属性,并且加入自己独特的属性sex

c.call() # 输出 Kitty 'Meow',Cat继承了父类Animal的 call methodTips:super(Cat, self).__init__(name,age) 去初始化父类,继承父类的 name和age两个属性。

super(Cat, self)返回当前类继承的父类,即 Animal类,然后调用__init__()方法(此时self参数已在super()中传入,在__init__()中将隐式传递,不用再写出self)。

二、Python 对子类方法的重构

当猫类 Cat 有自己的叫声 'prefer MMMEEEEEOW' ,可以对父类的method 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,'prefer MMMEEEEEOW')# rebuild

if __name__ == '__main__':

c = Cat('Kitty', 2, 'male')

c.call() # 输出:Kitty prefer MMMEEEEEOW 为子类定义的method call()在子类中重构父类的method后,Cat子类的实例先会在自己的类 Cat 中查找该方法,当找不到该方法时才会去父类 Animal 中查找对应的方法。

三、Python中子类与父类的关系

class Animal(object):

pass

class Cat(Animal):

pass

A= Animal()

C = Cat()

我们可以说:

“A”是 Animal 类的实例,但,“A”不是 Cat 类的实例。

“C”是 Animal 类的实例,“C”也是 Cat 类的实例。

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

判断对象之间的父子关系,通过 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? Trueisinstance() 不只可以用在我们自定义的类,也可以用于判断变量的类型,如判断数据类型是否为 int、str、list、dict 等。

print(isinstance(100, int))

print(isinstance('100', int))

print(isinstance(100, str))

print(isinstance('100', str))

输出:

True

False

False

True

四、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, '会“汪汪”叫')

定义一个 do 函数,接收一个变量 ‘all’,如下:

def do(all):

all.call()

A = Animal('小黑',4)

C = Cat('喵喵', 2, 'male')

D = Dog('旺财', 5, 'female')

for x in (A,C,D):

do(x)

输出:

小黑 会叫

喵喵 会“喵喵”叫

旺财 会“汪汪”叫

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

传递给函数 do(all) 的参数 all 不一定是 Animal 或 Animal 的子类型。任何数据类型的实例object都可以,只要它有一个 call() 的方法即可。其他不继承于 Animal类,具备 call 方法的也可以使用 do 函数。

这就是动态语言,动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。

五、Python类继承 注意事项:在继承中基类的构造方法(__init__())不会被自动调用,它需要在其派生类的构造方法中亲自专门调用。

在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量; 在类中调用普通method时不需要带上self参数

Python 总是首先查找对应类的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值