Python学习札记(三十三) 面向对象编程 Object Oriented Program 4
2017-02-26 10:33
525 查看
参考:继承和多态
NOTE
著名的开闭原则:对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的Animal_func()等函数。
1.eg.
#!/usr/bin/env python3 class Animal(object): """docstring for Animal""" def __init__(self): pass def run(self): print('Animal is running.') def printname(self): print('Animal') class Dog(Animal): """docstring for Dog""" def run(self): print('Dog is running') def printname(self): print('Dog') class Cat(object): """docstring for Cat""" def run(self): print('Cat is running') def printname(self): print('Cat') def Animal_func(obj): obj.run() def main(): a = Animal() b = Dog() c = Cat() a.run() b.run() c.run() Animal_func(a) Animal_func(b) Animal_func(c) if __name__ == '__main__': main()
sh-3.2# ./oop4.py Animal is running. Dog is running Cat is running Animal is running. Dog is running Cat is running
2.在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
继承的优点:
类Dog继承于类Animal,因此初始时Dog继承了父类的所有方法:
class Dog(Animal): pass # 继承了父类的所有方法 dog = Dog() dog.run()
Animal is running.
但也可以进行重写,当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。
eg.
class Animal(object): """docstring for Animal""" def __init__(self): pass def run(self): print('Animal is running.') def printname(self): print('Animal') class Dog(Animal): # Overrides the funcs of class Animal """docstring for Dog""" def run(self): print('Dog is running') def printname(self): print('Dog') dog = Dog() dog.run()
Dog is running
即是多态。
3.多态:当我们定义一个class的时候,我们实际上就定义了一种数据类型。
a = Dog()
>>> isinstance(a, Animal) True >>> isinstance(a, Dog) True
当一个对象是一个子类的对象时,这个对象也是该子类的父类的对象,也就是说,上文中a既是Dog的一个对象,也是Animal的一个对象。
多态的优点:
def Animal_func(obj): obj.run() a = Animal() b = Dog() c = Cat() Animal_func(a) Animal_func(b) Animal_func(c)
Animal is running. Dog is running Cat is running
当我们新增一个基于Animal的子类时,将该子类的对象传入Animal_func方法就能得到结果,但是我们无需对这个方法进行任何修改:调用方只管调用,不管细节。
著名的开闭原则:
对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的Animal_func()等函数。
任何类,最终都可以追溯到根类object。
4.静态语言 vs 动态语言
对于静态语言(Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。
对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了。
也就是说,静态语言中依赖于特定类的方法,传入的obj必须根正苗红,比如我们家的饮水机只给有倒水方法的我们家的人服务,虽然其他人也有倒水的方法,但是由于不是我们家的人,所以饮水机不工作。动态语言就不一样了,饮水机不管你是谁,只要你会倒水,那么就工作。
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
2017/2/26
相关文章推荐
- Python学习札记(三十七) 面向对象编程 Object Oriented Program 8 @property
- Python学习札记(三十五) 面向对象编程 Object Oriented Program 6
- Python学习札记(三十) 面向对象编程 Object Oriented Program 1
- Python学习札记(三十四) 面向对象编程 Object Oriented Program 5
- Python学习札记(三十八) 面向对象编程 Object Oriented Program 9
- Python学习笔记09_面向对象编程Object Oriented Programming
- Python学习札记(三十一) 面向对象编程 Object Oriented Program 2
- Python学习札记(三十二) 面向对象编程 Object Oriented Program 3
- Python学习札记(三十九) 面向对象编程 Object Oriented Program 10
- Python学习札记(三十六) 面向对象编程 Object Oriented Program 7 __slots__
- Python面向对象编程(Object-Oriented)和装饰器(decorator)
- Python学习札记(四十) 面向对象编程 Object Oriented Program 11
- Python Object Oriented Programming (面向对象编程) Generator
- Python学习 面向对象编程
- 面向对象编程(Object Oriented Programming)概念总结及延伸(一)
- Files and Strings(Chapter 10 of Python 3 Object Oriented Programming)
- 面向对象编程(Object Oriented Programming)概念及延伸(三)
- 面向对象编程(Object Oriented Programming)概念及延伸(二)
- When Objects are Alike(Chapter 3 of Python 3 Object Oriented Programming)
- Python3 Object Oriented Programming notes