python 学习笔记day08-面向对象编程

面向对象编程

OOP介绍

什么是OOP

编程的发展已经从简单控制流中按步的的指令序列进入到更有组织的方式中

结构化的或过程性编程可以让我们把程序组织成逻辑块,以便重复或重用

面向对象编程增强了结构化编程,实现了数据与动作的融合

数据层和逻辑层由一个可用以创建这些对象的简单抽象层来描述

常用术语

抽象/实现:抽象指对现实世界问题和实体的本质表现,行为和特征建模,建立一个相关的子集,可以用于描绘程序结构,从而实现这种模型

封装/借口:封装描述了对数据/信息进行隐藏的观念,它对数据属性提供接口和访问函数;客户端根本就不需要知道在封装之后,数据属性是如何组织的,这就需要在设计时,对数据提供相应的接口

合成:合成扩充了对类的描述,使得多个不同的类合成为一个大的类,来解决现实问题

派生/继承:派生描述了子类的创建,新类保留已存类类型中所有需要的数据和行为,但允许修改或者其他的自定义操作,都不会修改原类的定义

多态:指出了对象如何通过他们共同的属性和动作来操作及访问,而不需考虑他们具体的类

创建类

类是一种数据结构,我们可以用它来定义对象,对象把数据值和行为特性融合在一起

python使用class关键字来创建类

通常类名的第一个字母大写

class ClassName(bases):

‘class documentation string‘ #类文档字符串

class_suite #类体

类里面定义的函数 叫方法

类的数据属性

数据属性仅仅是所定义的类的变量

这种属性已是静态变量,或者是静态数据。他们表示这些数据是与它们所属的类对象绑定的,不依赖于任何类实例

静态成员通常仅用来跟踪与类相关的值

>>> class C(object):

...   foo = 100

...

>>> print C.foo

100

>>> C.foo += 1

>>> print C.foo

101

self指的是将对象本身传递到方法中,既将a对象本身传递到pstar方法中。

>>> class MyClass(object):

...   def pstar(self):

...     print ‘*‘ * 20

...

>>> a = MyClass()

>>> a.pstar()

********************

#!/usr/bin/env python

class AddrBook(object):

def __init__(self,nm,ph):

self.name = nm

self.phone = ph

self.city = "Beijing"

def get_name(self):

return self.name

def get_phone(self):

return self.phone

def update_phone(self,newph):

self.phone = newph

print "Now, %s phone number is: %s " % (self.name,self.phone)

if __name__ == ‘__main__‘:

bob = AddrBook("Bob Green","15011223344")

alice = AddrBook("Alice Smith","12255778899")

#print "%s: %s" % (bob.name,bob.phone) # 不应该直接使用类里面的数据属性,如果要是使用的话,需要定义一些类的方法

#print "%s: %s" % (alice.name,alice.phone)

print "%s: %s" % (bob.get_name(),bob.get_phone())

print "%s: %s" % (alice.get_name(),alice.get_phone())

bob.update_phone("186112233344")

print "%s: %s" % (bob.get_name(),bob.get_phone())

组合

什么是组合

类被定义后,目标就是要把它当成一个模块来使用,并把这些对象嵌入到你的代码中去

组合就是让不同的类混合并加入到其他类中来增加功能和代码重用性

可以在一个大点的类中创建其它类的实例,实现一些其他属性和方法来增强对原来的类对象

实现组合

创建复合对象、应用组合可以实现附加的功能

例如,通过组合实现上述地址簿功能的增强

#!/usr/bin/env python

class Info(object):

def __init__(self,ph,em,qq):

self.phone = ph

self.email = em

self.qq = qq

def get_phone(self):

return self.phone

def update_phone(self,newph):

self.phone = newph

class AddrBook(object):

def __init__(self,nm,ph,em,qq):

self.name = nm

self.info = Info(ph,em,qq)

if __name__ == ‘__main__‘:

bob = AddrBook("Bob Green","1250000000","[email protected]","11111111")

print bob.info.get_phone()

创建子类

当类之间有显著的不同,并且较小的类是较大的类所需要的组件时组合表现的很好;但当设计“相同的类但有些不同额功能”时,派生就是一个更加合理的选择了

OOP的更强大方面之一是能够使用一个已经定义好的类,扩展它或者对其进行修改,而不会影响系统中使用现存类的其他代码片段

OOD(面向对象设计)允许类特征在子孙类或子类中进行继承

继承

继承描述了基类的属性如何“遗传”给派生类

子类可以继承他的基类的任何属性,不管是数据属性还是方法

#!/usr/bin/env python

class AddrBook(object):

def __init__(self,nm,ph):

self.name = nm

self.phone = ph

self.city = "Beijing"

def get_name(self):

return self.name

def get_phone(self):

return self.phone

def update_phone(self,newph):

self.phone = newph

print "Now, %s phone number is: %s " % (self.name,self.phone)

class EmplAddrBook(AddrBook):   #类 EmplAddrBook并没有定义任何方法

pass

if __name__ == ‘__main__‘:

bob = EmplAddrBook("Bob Green","111111122222333")  #bob是类 EmplAddrBook的实例

print bob.get_phone()  # 类 EmplAddrBook继承了类AddrBook的方法,实例bob就具备了该功能

通过继承覆盖方法

如果子类中有和父类同名的方法,父类方法将被覆盖

如果需要访问父类的方法,则需要调用一个未绑定的父类方法,明确给出子类的实例

>>> class P(object):
                ...   def foo(self):
                ...     print "in P-foo"
                ...
                >>> class C(P):
                ...   def foo(self):
                ...     print "in C-foo"
                ...
                >>> c = C()
                >>> c.foo()
                in C-foo
                >>> P.foo(c)
                in P-foo

#!/usr/bin/env python

class AddrBook(object):

def __init__(self,nm,ph):

self.name = nm

self.phone = ph

self.city = "Beijing"

def get_name(self):

return self.name

def get_phone(self):

return self.phone

def update_phone(self,newph):

self.phone = newph

print "Now, %s phone number is: %s " % (self.name,self.phone)

class EmplAddrBook(AddrBook):

def __init__(self,nm,ph,em,eid):

AddrBook.__init__(self,nm,ph)

self.email = em

self.eid = eid

def get_email(self):

return self.email

if __name__ == ‘__main__‘:

bob = EmplAddrBook("Bob Green","111111122222333","[email protected]","1024")

print bob.get_phone()

print bob.get_email()

多重继承

python允许多重继承,即一个类可以是多个父类的子类,子类可以拥有所有父类的属性

>>> class A(object):
                ...   def foo(self):
                ...     print "foo method"
                ...
                >>> class B(object):
                ...   def bar(self):
                ...     print "bar methon"
                ...
                >>> class C(A,B):
                ...   pass
                ...
                >>> c = C()
                >>> c.foo()
                foo method
                >>> c.bar()
                bar methon

特殊的类属性

属性 描述
C.__name__ 类C的名字(字符串)
C.__doc__ 类C的文档字符串
C.__bases__ 类C的所有父类构成的元组
C.__dict__ 类C的属性
C.__module 类C定义所在的模块
C.__class__ 实例C对应的类

实例

创建实例

如果说类是一种数据结构定义类型,那么实例则声明了一个这种类型的变量

类被实例化得到实例,该实例的类型就是这个被实例化的类

创建实例与调用函数类似,调用一个类就创建了它的一个实例

>>> class C(object):

...   foo = 100

...

>>> c = C()

>>> print c

<__main__.C object at 0x7f7f2d721350>

实例属性

实例仅拥有数据属性,数据属性只是与某个累的实例相关联的数据值,并且可通过句点属性标识法来访问

设置实例的属性可以在实例创建后任意时间进行,也可以在能够访问实例的代码中进行

>>> class C(object):

...   pass

...

>>> c = C()

>>> c.hi = ‘hello‘

>>> print c.hi

hello

特殊的实例属性

类与实例属性对比

绑定方法

方法仅仅是类内部定义的函数,方法只有在其所属的类拥有实例时,才能被调用

任何一个方法定义中的第一个参数变量都是self,它表示调用此方法的实例对象

非绑定方法

调用非绑定方法并不常用到

需要调用一个没有实例的类中的方法的一个主要场景是你在派生一个子类,而且要覆盖父类的方法

class AddrBook(object):

def __init__(self,nm,ph):

self.name = nm

self.phone = ph

self.city = "Beijing"

class EmplAddrBook(AddrBook):

def __init__(self,nm,ph,em,eid):

AddrBook.__init__(self,nm,ph)

self.email = em

self.eid = eid

def get_email(self):

return self.email

类和实例的内建函数

函数 功能
rissubclass() 判断一个类是另一个类的子类或子孙类
isinstance() 在判定一个对象是否是另一个给定类的实例
hasattr() 判断一个对象是否有一个特定的属性
getattr() 获得一个对象的属性值
setattr() 设置一个对象的属性
delattr() 删除一个对象的属性

私有化

python为类元素(属性和方法)的私有性提供初步的形式,由双下划线开始的属性在运行时被“混淆”,所以直接访问是不允许的

>>> class C(object):
                ...   def __init__(self,nm):
                ...     self.__name = nm
                ...   def getName(self):
                ...     return self.__name
                ...
                >>> c = C(‘bob‘)
                >>> c.getName()
                ‘bob‘
                >>> c.__name  #私有化的数据不能在外部直接使用
                Traceback (most recent call last):
                  File "<stdin>", line 1, in <module>
                AttributeError: ‘C‘ object has no attribute ‘__name‘

>>> c._C__name
                ‘bob‘

#!/usr/bin/env python
#coding: utf8
class Book(object):
    def __init__(self,title,author):
        self.title = title
        self.author = author
    def __str__(self):
        return self.title
    def __call__(self):
        print "%s is written by %s" % (self.title,self.author)
if __name__ == ‘__main__‘:
    pybook = Book("Core Pyhon","Wesley")
    print pybook  # 因为类中定义了__str__方法,此处打印出的内容是__str__的返回值
    pybook()  #调用pybook就是执行 __call__方法中的代码

左加法,右加法,左减法,右减法

#!/usr/bin/env python

#coding: utf8

class MyNumber(object):
    def __init__(self,num):
        self.number = num
    def __add__(self,other):
        return self.number + other
    def __radd__(self,other):
        return self.number + other
    def __sub__(self, other):
        return self.number - other
    def __rsub__(self, other):
        return other - self.number
if __name__ == ‘__main__‘:
    digit = MyNumber(10)
    print digit + 10   # 用__add__实现
    print 10 + digit   # __radd__

print digit - 100  # __sub__

print 100 - digit  # __rsub__

魔法方法不是随便起名字的。必须遵循对应的名字

时间: 2024-08-17 19:55:46

python 学习笔记day08-面向对象编程的相关文章

python 学习笔记7 面向对象编程

一.概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." 二.创建类和对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 "类" 和 "对象" 来实现,所以,面向对象编程其实就是对 "类" 和 "对象" 的使用. 类就是一个模板,模板里可以包含多个函数,函数里实现一些功能 对象

python学习笔记(七):面向对象编程、类

一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一个功能.举个例子,你要做饭,可以用电磁炉,也可以用煤气灶.不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路,两种最重要的编程范式分别是面向过程编程和面向对象编程. 提到面向对象,就不得不提到另一种编程思想,面向过程:什么是面向过程呢,面向过程的思想是把一个项目.一件事情按照一定的顺

python学习笔记之面向对象编程特性(二)

面向对象程序设计中的术语对象(Object)基本上可以看做数据(特性)以及由一系列可以存取.操作这些数据的方法所组成的集合.传统意义上的"程序=数据结构+算法"被封装"掩盖"并简化为"程序=对象+消息".对象是类的实例,类的抽象则需要经过封装.封装可以让调用者不用关心对象是如何构建的而直接进行使用. 首先说明一下python编程规范: #!/usr/bin/env python #coding=utf-8 #编程规范,示例如下:   class 

python学习笔记(六) - 面向对象编程

一. 类和实例 aa 二. 访问限制 bb 三. 继承和多态 cc 四. 获取对象信息 dd

day10_python学习笔记_chapter13_面向对象编程

1. class NewClass(parent): def .... 如果没有父类, 则默认继承object类 2. 类属性访问(类似java中的静态属性和方法)直接用类名.属性名, 在python中, 如果没有创建实例, 方法不能被调用.方法必须绑定到一个实例才能直接被调用. class C(object): foo = 100 访问 C.foo 3. 特殊的类属性: C.__name__, C.__doc__ , C.__bases__, C.__dict__ , C.__module__

python学习笔记12-python面向对象

python学习笔记12-python面向对象 python一切皆对象 一.基本概念 1.面向对象和面向过程 面向对象编程:C++,Java,Python 面向过程编程:函数式编程,C程序等 2.类和对象 类:是对事物的抽象,比如:人类,球类 对象:是类的一个实例,比如:足球,篮球,对象就是对类的实例化 属性:五官,眼,鼻子,理解为一个变量,静态属性 方法:对人来说,吃穿住行,理解为一个函数,动态方法 实例说明:球类可以对球的特征和行为进行抽象,然后可以实例化一个真实的球实体出来 3.为什么要使

C++ Primer 学习笔记_73_面向对象编程 --再谈文本查询示例

面向对象编程 --再谈文本查询示例 引言: 扩展第10.6节的文本查询应用程序,使我们的系统可以支持更复杂的查询. 为了说明问题,将用下面的简单小说来运行查询: Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful fiery bird, he

C++ Primer 学习笔记_74_面向对象编程 --再谈文本查询示例[续/习题]

面向对象编程 --再谈文本查询示例[续/习题] //P522 习题15.41 //1 in TextQuery.h #ifndef TEXTQUERY_H_INCLUDED #define TEXTQUERY_H_INCLUDED #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <set> #include <map&g

C++ Primer 学习笔记_66_面向对象编程 --定义基类和派生类[续]

算法旨在用尽可能简单的思路解决问题,理解算法也应该是一个越看越简单的过程,当你看到算法里的一串概念,或者一大坨代码,第一感觉是复杂,此时不妨从例子入手,通过一个简单的例子,并编程实现,这个过程其实就可以理解清楚算法里的最重要的思想,之后扩展,对算法的引理或者更复杂的情况,对算法进行改进.最后,再考虑时间和空间复杂度的问题. 了解这个算法是源于在Network Alignment问题中,图论算法用得比较多,而对于alignment,特别是pairwise alignment, 又经常遇到maxim

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数、抽象类、虚析构函数、动态创建对象

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数.抽象类.虚析构函数.动态创建对象 一.纯虚函数 1.虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 2.如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 3.在基类中不能给出有意义的虚函数定义,这时可以把它声明成纯虚函数,把它的定义留给派生类来做 4.定义纯虚函数: class <类名> { virtual <类型> <函