面对过程的程序设计方法意在将函数分成子函数,再依次调用这些函数来解决问题。

  而面对对象的程序设计方法,来源于自然界,类是实例的抽象,实例是类的具体。自定义出来的对象是类,而所有的数据都可以看成是对象,因此解决问题的方法是靠对象自己处理消息和相互传递消息。使用时,首先考虑的是需要创建什么样的对象,对象中有怎么样的属性,要实现什么功能(成为方法)。

  面向对象的抽象程度比函数要高,因为一个class中既包含数据,又包含操作数据的方法。其中,数据封装、继承和多态是面向对象的三大特点。

  创建类时,class后面跟类名,()中是所继承的类,没有特别的父类就写object,类中定义的第一个方法是__init__(self,.....),这是通过类创建实例时传入一些内部参数所需要的初始方法,如下:

class Student(object):

    def __init__(self, name, score):
self.name = name
self.score = score
>>> bart = Student('Bart Simpson', 59)
>>> bart.name
'Bart Simpson'
>>> bart.score
59

  依据所需的属性和功能设计类中的变量和方法,由类加上特定的参数创建特定的实例,之后对于所需要查看和调用的函数全部由实例内部实现,外部无需知道内部的实现细节,只管使用就OK了,这就是所谓的数据封装。

  • 数据访问权限

  对于对象的属性尽量封装,保证对象的独立完整性。也就是说,对于属性的修改和调用靠类自己内部实现和处理,这对于面向对象编程是很有好处的。不仅可以保证外部代码无法随意修改对象内部的状态,同时,在方法中,也可以对参数做检查,避免传入无效的参数。

  以双下划綫开头__,表示私有属性,无法访问;单下划线_开头,表示按照常用规则,应该看成私有属性;而以双下划綫__开头和结尾,表示这是个特殊属性,可以直接访问。

  例如创建Student类时,其中的属性name和score应该设成私有属性,保证数据的安全;同时,在类中的方法,增加修改的方法,提供接口:

class Student(object):

    def __init__(self, name, score):
self.__name = name
self.__score = score def print_score(self):
print '%s: %s' % (self.__name, self.__score)   def get_name(self):
    return self.__name   def get_score(self):
    return self.__score   def set_score(self, score):
    if 0<=score<=100:
      self.__score = score
    else:
      raise ValueError("bad score")
  • 继承和多态

  在面向对象编程中,定义一个变量时,可以选择从已有的类中继承。这样,已有的类成为父类,新创建的类成为子类。子类继承父类的所有属性,也可在子类中重新定义属性,将会替换掉继承自父类的该属性。

  多态是指当以父类为参数传入函数中时,继承该父类的所有子类都可以作为参数传入实现相应的功能。

  例如已有Animal类,以Animal作为父类,创建新的子类Dog,Cat,而以Animal类为参数的run_twice函数,对于Dog、Cat类同样有效。

class Animal(object):
def run(self):
print 'Animal is running...'
class Dog(Animal):
def run(self):
print 'Dog is running...' class Cat(Animal):
def run(self):
print 'Cat is running...
def run_twice(animal):
animal.run()
animal.run()
>>> run_twice(Animal())
Animal is running...
Animal is running...
>>> run_twice(Dog())
Dog is running...
Dog is running...
>>> run_twice(Cat())
Cat is running...
Cat is running...

  而如果新增加了一个子类Tortoise,该函数同样可行。

class Tortoise(Animal):
def run(self):
print 'Tortoise is running slowly...'
>>> run_twice(Tortoise())
Tortoise is running slowly...
Tortoise is running slowly...

  这就是著名的“开闭”原则:

  对扩展开放:允许新增Animal子类;

  对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

  • 获取对象信息

  使用type():type方法只允许传入单个参数,返回该参数的type类型,做type类型判断时,注意import types

>>> import types
>>> type('abc')==types.StringType
True
>>> type(u'abc')==types.UnicodeType
True
>>> type([])==types.ListType
True
>>> type(str)==types.TypeType
True

  使用isinstance():isinstance方法允许传入两个参数,第一个是待判断对象,第二个是类型

>>> isinstance('a', str)
True
>>> isinstance(u'a', unicode)
True
>>> isinstance('a', unicode)
False

或者判断是否是某些类型中的一种:

>>> isinstance('a', (str, unicode))
True
>>> isinstance(u'a', (str, unicode))
True

  使用dir():dir方法是获得一个对象的所有属性和方法。

>>> dir('ABC')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

  属性中以双下划线__开头和结尾的,是特殊属性,可在自己写的对象中添加该属性的方法,达到一定的效果。

>>> class MyObject(object):
... def __len__(self):
... return 100
...
>>> obj = MyObject()
>>> len(obj)
100

  另外,如果不知道某个属性是否属于该对象,可以进行如下操作:

>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19

getattr可以传入默认显示值:

>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404
404

注:本文为学习廖雪峰Python入门整理后的笔记

Day-8: 面对对象编程的更多相关文章

  1. python面对对象编程----2:__init__

    面对对象编程估计我们最早接触到的就是__init__了,也就是实例的初始化处理过程: 1:来看看最基础的__init__ class Card(object): #抽象类Card,并不用于实例化 de ...

  2. 面对对象编程(OOP, Object Oriented Programming)及其三个基本特性

    一千个读者,一千个哈姆雷特.对于面对对象编程,书上都会告诉我们它有三个基本特性,封装,继承,多态,但谈起对这三点的见解,又是仁者见仁智者见智,感觉还是得多去编程中体验把 . 面向对象编程(OOP, O ...

  3. Python学习6——再谈抽象(面对对象编程)

    1.对象魔法 在面对对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法. 使用对象而非全局变量以及函数的原因有多个,而最重要的好处不过以下几点: 多态:可对不同类型的对象 ...

  4. C++ 基础语法 快速复习笔记---面对对象编程(2)

    1.C++面对对象编程: a.定义: 类定义是以关键字 class 开头,后跟类的名称.类的主体是包含在一对花括号中.类定义后必须跟着一个分号或一个声明列表. 关键字 public 确定了类成员的访问 ...

  5. 跟着百度学PHP[4]OOP面对对象编程-7-OOP的一些关键子讲解

    面对对象常用的一些关键子:http://www.cnblogs.com/xishaonian/p/6146794.html排版不是很好望见谅. THE END

  6. js面对对象编程(二):属性和闭包

    上篇博客中解说了一些js对象的基本概念和使用方法.这篇博客解说一下js属性方面的:公有属性.私有属性,特权方法. 假设学过java.公有属性.私有属性,特权方法(即能够訪问和设置私有属性的方法)一定非 ...

  7. js面对对象编程

    说到js,非常大一部分人会说我非常熟悉,在日常的web开发中经经常使用,那么你的js代码是符合面对对象思路的吗?那你会问我面向过程的js代码有什么不好吗?我的感受是面对对象的js编码更加简洁,降低了混 ...

  8. 跟着百度学PHP[4]-OOP面对对象编程-1-什么是面对对象编程

    该阶段学习参考:http://www.cnblogs.com/xiaochaohuashengmi/archive/2010/09/10/1823042.html 面向对象编程(Object Orie ...

  9. 浅谈Perl的类、包、模块与面对对象编程

    http://blog.chinaunix.net/uid-27464093-id-3308003.html Perl面向对象 Perl面向对象学习例子实例代码教程 - 在我们了解perl的面向对象的 ...

随机推荐

  1. [补档][Tvyj 1729]文艺平衡树

    [Tvyj 1729]文艺平衡树 题目 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结 ...

  2. 深搜(DFS)广搜(BFS)详解

    图的深搜与广搜 一.介绍: p { margin-bottom: 0.25cm; direction: ltr; line-height: 120%; text-align: justify; orp ...

  3. hdu--1316--How Many Fibs?(java大数)

    How Many Fibs? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  4. recycleView 使用指南1

    最近看了很多 recycleView 的使用文章,一直晕乎乎的,完全不知道套路是啥.很多人都是直接上代码,但是却没有详细说明代码的使用,于是打算自己写写,理理思路.顺便帮助那些正在学习 android ...

  5. ABP:在多语句事务内不允许使用 CREATE DATABASE 语句

    一.问题 使用ef codefirst开发,无法创建数据库的问题,如下提示 Server Error in '/' Application. 在多语句事务内不允许使用 CREATE DATABASE ...

  6. TCP/IP卷一:第一章

    ================================================= 版權聲明:如需轉載,請列明出處:HingAglaiaWong@博客園 支持原創,是對作者最好的的鼓勵 ...

  7. android四大组件学习总结以及各个组件示例(1)

    android四大组件分别为activity.service.content provider.broadcast receiver. 一.android四大组件详解 1.activity (1)一个 ...

  8. 【机器学习笔记之一】深入浅出学习K-Means算法

    摘要:在数据挖掘中,K-Means算法是一种 cluster analysis 的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法. 在数据挖掘中,K-Means算法是一种c ...

  9. MyBatis从入门到放弃六:延迟加载、一级缓存、二级缓存

    前言 使用ORM框架我们更多的是使用其查询功能,那么查询海量数据则又离不开性能,那么这篇中我们就看下mybatis高级应用之延迟加载.一级缓存.二级缓存.使用时需要注意延迟加载必须使用resultMa ...

  10. virtual与static

    virtual与static不能同时作用于一个函数.根据面向对象的理论,virtual的成员函数是可以变子类覆盖的,是实现多态的重要手段.而static作用的成员函数表示该函数仅属于某个类. 下面是实 ...