Python的继承与多态

Posted by Csming on 2017-04-17

我们定义跟一个class的时候,可以从某个现有的class继承,新的class就是子类;
被继承的class叫做基类(就是老被啦~)


初次使用继承

首先编写一个基类;
然后编写子类,直接继承基类;此时,子类的实例就可以直接调用父类的方法了;(如Dog类)

当然,子类可以定义自己的方法;
而如果子类定义了与父类的方法重名时,就会将父类的方法覆盖

1
2
3
4
5
6
7
8
9
10
11
12
13
class Animal(object):
def run(self):
print('Animal is running')

class Dog(Animal):
pass

class Cat(Animal):
def run(self):
print('Cat is running...')

def eat(self):
print('Eating meat...')

当子类覆盖父类的方法时,通过子类实例调用该方法时,就会直接调用子类的方法
这样的属性成为:多态

多态

如以上栗子;
我们通过Dog()声明一个dog变量时,dog是一个Dog对象,同时也是Animal对象;

如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类
然而,反之不可

当传入接受参数为父类实例的函数时,可以将子类实例向上转型为父类对象

对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数


对比静态语言与动态语言

**对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。

对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了**

我这心里简直卧槽卧槽的……好厉害……


获取对象信息

type()

type()用来判断对象类型

当一个变量指向函数或者类的时候,也可以用type()来判断

type()函数返回对应的Class类型

isinstance()

对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数

dir()

获取一个对象的所有属性和方法;
返回一个包含字符串的list;


实例属性和类属性

动态语言,类创建的实例可以任意绑定属性
给实例绑定属性的方法时通过实例变量,或者通过self变量;

如果类要绑定一个属性(类属性):
可以直接在class中定义属性;

1
2
class Student(object):
name = 'Student'

可以通过实例名或者类名访问;


参考资料:http://www.liaoxuefeng.com/