zoukankan      html  css  js  c++  java
  • Python面向对象特征总结

    抽象是隐藏多余细节的艺术。在面向对象的概念中,抽象的直接表现形式通常为类。Python基本上提供了面向对象编程语言的所有元素,如果你已经至少掌握了一门面向对象语言,那么利用Python进行面向对象程序设计将会相当容易。

    一、封装

    面向对象程序设计中的术语对象(Object)基本上可以看做数据(特性)以及由一系列可以存取、操作这些数据的方法所组成的集合。传统意义上的“程序=数据结构+算法”被封装”掩盖“并简化为“程序=对象+消息”。对象是类的实例,类的抽象则需要经过封装。封装可以让调用者不用关心对象是如何构建的而直接进行使用。

    一个简单的Python类封装如下:

    Encapsulation

    上面简单的示例代码可以看出,Python中的类包含了一般面向对象编程语言的主要元素,比如构造方法、绑定方法、静态方法、属性等,如果深入下去,还可以发现Python中内置了很多面向对象的“高级”主题,比如迭代器反射特性等等,提供了封装的直接构造要素。

    二、继承

    1、类继承

    继承给人的直接感觉是这是一种复用代码的行为。继承可以理解为它是以普通的类为基础建立专门的类对象,子类和它继承的父类是IS-A的关系。一个简单而不失经典的示例如下:

    Inheritance

    一个显而易见的特点是,Python的面向对象的继承特征是基于类(class)的,比javascript基于原型(prototype)的继承更容易组织和编写代码,也更容易让人接受和理解。

    ps:最近几天Anders大神搞出来的TypeScript横空出世,看它的语言规范里继承也是基于类的:

    TypeScript-SimpleInheritance

    感觉基于类的继承的语言好像在实现OO的可读性和编程体验上都不太差,据传说javascript是码农最想喷也是喷过最多f**k的语言。

    2、多重继承

    不同于C#,Python是支持多重类继承的(C#可继承自多个Interface,但最多继承自一个类)。多重继承机制有时很好用,但是它容易让事情变得复杂。一个多重继承的示例如下:

    MultInheritance

    如你所看到的那样,多重继承的好处显而易见,我们可以轻而易举地通过类似“组合”的方式复用代码构造一个类型。

    有个需要注意的地方,即如果一个方法从多个超类继承,那么务必要小心继承的超类(或者基类)的顺序:

    MultInheritance

    我们为动物和机器各实现一个相同名称的move方法,但是输出因为继承的顺序而有所不同,Python在查找给定方法或者特性时访问超类的顺序被称为MRO(Method Resolution Order,方法判定顺序)。

    三、多态

    多态意味着可以对不同的对象使用同样的操作,但它们可能会以多种形态呈现出结果。在Python中,任何不知道对象到底是什么类型,但又需要对象做点什么的时候,都会用到多态。

    能够直接说明多态的两段示例代码如下:

    1、方法多态

    Method-Polymorphism

    对于一个临时对象obj,它通过Python的随机函数取出来,不知道具体类型(是字符串、元组还是自定义类型),都可以调用count方法进行计算,至于count由谁(哪种类型)去做怎么去实现我们并不关心。

    有一种称为”鸭子类型(duck typing)“的东西,讲的也是多态:

    DuckTyping

    就in_the_forest函数而言,参数对象是一个鸭子类型,它实现了方法多态。但是实际上我们知道,从严格的抽象来讲,Person类型和Duck完全风马牛不相及。

    2、运算符也多态

    Operator-Polymorphism

    上例中,显而易见,Python的加法运算符是”多态“的,理论上,我们实现的add方法支持任意支持加法的对象,但是我们不用关心两个参数x和y具体是什么类型。

    一两个示例代码当然不能从根本上说明多态。普遍认为面向对象最有价值最被低估的特征其实是多态。我们所理解的多态的实现和子类的虚函数地址绑定有关系,多态的效果其实和函数地址运行时动态绑定有关。在C#中实现多态的方式通常有重写重载两种,从上面两段代码,我们其实可以分析得出Python中实现多态也可以变相理解为重写和重载。在Python中很多内置函数和运算符都是多态的。

    号外:在C#中,我们熟知接口(Interface)和多态相关,在处理多态对象时,只要关心它的接口(或者称为“协议”)而不需要显式指定特定实现类型即可,这也是IoC中面向接口(抽象)而不依赖于具体实现编程的基础。可惜在Python中根本没有Interface(有抽象类)。而在TypeScript的Specification中引入了Interface的概念:

    TypeScript-Interface

    TypeScript语言规范里对Interface的定义是命名的对象类型(Programmers can give names to object types; we call named object types interfaces. )。它直接等价于下面的Ojbect Type:

    var Friend: () => {
        name: string; favoriteColor?: string;
    };

    上面这个Object Type在Playgound中等价的javascript代码如下:

    var Friend;

    在TypeScript编程规范文档里,对Interface的一些说明:

    Interfaces provide the ability to give names to object types and the ability to compose existing named object types into new ones.
    Interfaces have no run-time representation—they are purely a compile-time construct. Interfaces are particularly useful for documenting and validating the required shape of properties, objects passed as parameters, and objects returned from functions
    .

    Interface可以继承自Interface:

    TypeScript-InterfaceInheritInterface

    我们尝试让类继承自Interface:

    TypeScript-ClassInheritInterface

    实践证明类是不能继承实现Interface的:A export class may only extend other classes, Mover is an interface.

    现在大家知道TypeScript里的Interface和我们所认识和理解的接口的区别了吗?相同的一个名词Interface,不同语境下意义并不完全相同,看上去好像是挺傻的,但是学习和使用语言不做对比几乎是不可能的。

    参考:

    http://www.python.org/

    http://zh.wikipedia.org/wiki/Duck_typing

    http://typescript.codeplex.com/

    http://www.typescriptlang.org/Playground/

    http://www.nczonline.net/blog/2012/10/04/thoughts-on-typescript/

  • 相关阅读:
    AX 2012 Security Framework
    The new concept 'Model' in AX 2012
    How to debug the SSRS report in AX 2012
    Using The 'Report Data Provider' As The Data Source For AX 2012 SSRS Report
    Deploy SSRS Report In AX 2012
    AX 2012 SSRS Report Data Source Type
    《Taurus Database: How to be Fast, Available, and Frugal in the Cloud》阅读笔记
    图分析理论 大纲小结
    一文快速了解Posix IO 缓冲
    #转载备忘# Linux程序调试工具
  • 原文地址:https://www.cnblogs.com/jeffwongishandsome/p/2713258.html
Copyright © 2011-2022 走看看