把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

一:封装(类内的事)

对于类的方法而言,对外只知道功能隐藏细节

假设我们要处理学生的成绩表,为了表示一个学生的成绩,面向过程的程序可以用一个dict表示:
#面向程序
std1 = { 'name': 'Michael', 'score': 98 }
std2 = { 'name': 'Bob', 'score': 81 } def print_score(std):
print('%s: %s' % (std['name'], std['score'])) #面向对象
class Student(object): # 继承类object,所有类最终都会继承的类
  #属性
  def __init__(self, name, score):
    self.name = name self.score = score
  #数据封装,类的方法,为了和类关联起来
  def print_score(self):
    print('%s: %s' % (self.name, self.score)) #封装的另一个好处是可以给Student类增加新的方法
def get_grade(self):
if self.score >= 90:
return 'A'
elif self.score >= 60:
return 'B'
else:
return 'C'
#给对象发消息就是调用对象对应的关联函数,称为对象的方法,实例
bart = Student('Bart Simpson', 59)
bart.print_score()
#类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响;

访问限制

#属性的名称前加上两个下划线__,私有变量(private),只有内部可以访问
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)) #如果外部代码要获取name和score怎么办?可以给Student类增加get_name和get_score这样的方法
def get_name(self):
return self.__name def get_score(self):
return self.__score #如果又要允许外部代码修改score
def set_score(self, score):
self.__score = score #bart.score = 59也可以修改,因为在方法中,可以对参数做检查,避免传入无效的参数
def set_score(self, score):
if 0 <= score <= 100:
self.__score = score
else:
raise ValueError('bad score') #变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的 #一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的但是约定为私有变量 #不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名
>>> bart._Student__name
'Bart Simpson'

二:继承(类之间的事)

子类从属父类的属性和方法,也可自己定义,覆盖父类或添加。

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)

 class Animal(object):
def run(self):
print('Animal is running...') #继承
#对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类
class Dog(Animal):
pass class Cat(Animal):
pass #子类获得了父类的全部功能
dog = Dog()
dog.run()
#结果
Animal is running... #可以对子类增加一些方法
class Dog(Animal): def run(self):
print('Dog is running...') def eat(self):
print('Eating meat...') #子类和父类都存在相同的run()方法时,子类的run()覆盖了父类的run()
dog = Dog()
dog.run()
#结果,多态
Dog is running...

三:多态

定义一个class的时候,实际上就定义了一种数据类型,和Python自带的数据类型,比如str、list、dict没什么两样

 a = list() # a是list类型
b = Animal() # b是Animal类型
c = Dog() # c是Dog类型 #判断一个变量是否是某个类型可以用isinstance()
>>> isinstance(a, list)
True
>>> isinstance(b, Animal)
True
>>> isinstance(c, Dog)
True
#个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类
>>> isinstance(c, Animal)
True
#反过来就不行
>>> isinstance(b, Dog)
False

传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法

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...

著名的“开闭”原则:

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

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

静态语言和动态语言

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

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

这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子

python, 面向对象编程Object Oriented Programming(OOP)的更多相关文章

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

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

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

    参考:继承和多态 NOTE 著名的开闭原则: 对扩展开放:允许新增Animal子类: 对修改封闭:不需要修改依赖Animal类型的Animal_func()等函数. 1.eg. #!/usr/bin/ ...

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

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

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

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

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

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

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

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

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

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

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

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

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

    参考:访问限制 NOTE 1.eg. #!/usr/bin/env python3 class Student(object): """docstring for Stu ...

随机推荐

  1. C++ 0x

  2. Struts2_中文问题

    1.如果有中文,表单提交就用POST方式,别用GET方式. 2.配置 <constant name="struts.i18n.encoding" value="UT ...

  3. Python基础学习之序列(1)

    序列 序列类型有着相同的访问模式:它的每一个元素可以通过指定一个偏移量的方式得到.而多个元素可以通过切片操作的方式一次得到,下标偏移量是从0开始到总元素-1结束,之所以要减1是因为我们是从0开始计数的 ...

  4. PHP:如果正确加载js、css、images等静态文件

    日常中,我们想要把一些静态页面放在框架上或者是进行转移时,那么静态页面上的原url加载js.css.images都会失效,那么我们应该怎么进行修改捏? 现在仓鼠做个笔记哈 这里有几个注意项: 1.路径 ...

  5. java文件

    File类 为了很方便的代表文件的概念,以及存储一些对于文件的基本操作,在java.io包中设计了一个专门的类——File类. 在File类中包含了大部分和文件操作的功能方法,该类的对象可以代表一个具 ...

  6. 写给future的话

    学习任何事务,永远不要被繁复的表象所迷惑. 觉得自己知识不够深,了解的不够多,其实就是思考感悟的不够罢了. 想,都是问题,做,才有答案 换位思考是人际交往最重要的能力之一.

  7. UVA-674 Coin Change---完全背包

    题目链接: https://vjudge.net/problem/UVA-674 题目大意: 有5种硬币, 面值分别为1.5.10.25.50,现在给出金额,问可以用多少种方式组成该面值. 思路: 每 ...

  8. ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id

    远程删除key ssh-keygen -f "~/.ssh/known_hosts" -R 192.168.0.34 如果还是不可以,通过 ssh-keygen 重新生成key

  9. 【CCPC-Wannafly Winter Camp Day3 (Div1) G】排列(水题)

    点此看题面 大致题意:已知 \(p\)为\(n\)的一个排列,定义\(A(p)_i=min_{j=1}^ip_j\),若用\(q_i\)表示\(p\)第\(i\)小的前缀的长度(以值为第一关键字,下标 ...

  10. NYOJ 士兵杀敌(1~5)

    士兵杀敌(1): http://acm.nyist.net/JudgeOnline/problem.php?pid=108 分析:前缀和 #include <bits/stdc++.h> ...