参考:继承和多态

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 4的更多相关文章

  1. Python学习札记(三十) 面向对象编程 Object Oriented Program 1

    参考:OOP NOTE 1.面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. ...

  2. Python学习札记(三十七) 面向对象编程 Object Oriented Program 8 @property

    参考:@property NOTE 1.在绑定参数时,为了避免对属性不符合逻辑的操作,需要对传入的参数进行审核. #!/usr/bin/env python3 class MyClass(object ...

  3. Python学习札记(三十一) 面向对象编程 Object Oriented Program 2

    参考:类和实例 注意理解第七点. NOTE: 1.类是抽象的模板,比如Student类,实例是根据类创建出来的一个个具体的"对象",每个对象都拥有相同的方法,但各自的数据可能不同. ...

  4. Python学习札记(四十) 面向对象编程 Object Oriented Program 11

    参考:使用元类 NOTE: type() 1.type()函数可以用于检查一个类或者变量的类型. #!/usr/bin/env python3 class Myclass(object): " ...

  5. Python学习-第三天-面向对象编程基础

    Python学习-第三天-面向对象编程基础 类和对象 简单的说,类是对象的蓝图和模板,而对象是类的实例.这个解释虽然有点像用概念在解释概念,但是从这句话我们至少可以看出,类是抽象的概念,而对象是具体的 ...

  6. Python学习札记(三十四) 面向对象编程 Object Oriented Program 5

    参考:获取对象信息 NOTE 1.type()函数可以用来判断对象的类型: >>> type(123) <class 'int'> >>> type(' ...

  7. Python学习札记(三十八) 面向对象编程 Object Oriented Program 9

    参考:多重继承 NOTE #!/usr/bin/env python3 class Animal(object): def __init__(self, name): self.name = name ...

  8. Python学习札记(三十六) 面向对象编程 Object Oriented Program 7 __slots__

    参考:slots NOTE 1.动态语言灵活绑定属性及方法. #!/usr/bin/env python3 class MyClass(object): def __init__(self): pas ...

  9. Python学习札记(三十五) 面向对象编程 Object Oriented Program 6

    参考:实例属性和类属性 NOTE Python是动态语言,根据类创建的实例可以任意绑定属性. class Student(object): def __init__(self, name): self ...

随机推荐

  1. python搭建简易Web Server

    如果你急需一个简单的Web Server,但你又不想去下载并安装那些复杂的HTTP服务程序,比如:Apache,ISS等.那么, Python可能帮助你,使用Python可以完成一个简单的内建 HTT ...

  2. Struts2中的OGNL详解 《转》

    首先了解下OGNL的概念: OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的 ...

  3. 服务器报错 500,请确保 ASP.NET State Service(ASP.NET 状态服务)已启动

    报错信息: 解决方案: 开启此服务

  4. {sharepoint} More on SharePoint 2010 Application Pools

    More on SharePoint 2010 Application Pools Print | posted on Friday, December 04, 2009 3:26 PM Blimey ...

  5. {Repeater控件} Repeater控件的用法流程及实例

    一.Repeater控件的用法流程及实例: 1.首先建立一个网站,新建一个网页index.aspx. 2.添加或者建立APP_Data数据文件,然后将用到的数据库文件放到APP_Data文件夹中. 3 ...

  6. Linux操作系统上ADSL拨号上网的方法详解

    1.安装 yum install rp-pppoe.x86_64 2.配置PPPOE客户端软件 安装完软件包后,必须配置pppoe的配置文件/etc/ppp/pppoe.conf,从而让ADSL拨号时 ...

  7. Vanish/squid

    http://www.yl1001.com/article/5291411898652918.htm HTTP加速 简单的说,在本次测试中,Varnish将来自80的请求转发到后端的nginx8080 ...

  8. Django - 模型层 - 下

    一.多表 sql 单表 多表 多对一 多对多 一对一 =============================================== 一对多:Book id title price p ...

  9. mysql参数安全设置

    MySQL安全相关的参数有哪些?该如何配置? 1.MySQL数据安全 innodb_flush_log_at_trx_commit =1 #innodb每次提交事务redo buffer 刷新到red ...

  10. OpenStack功能简介

    为什要用云? 一.简单的说就是对资源更加合理的分配,使用,比如硬件的数量,带宽等等这些,因为你不能机器买来不需要了再卖掉(当然也可以),带宽跟机房签合同得来一年的,中间不够了也不能加,超了也不退钱 二 ...