python之面相对象程序设计

一 面向对象的程序设计的由来

面向对象设计的由来见概述:http://www.cnblogs.com/linhaifeng/articles/6428835.htmljavascript

面向对象的程序设计:路飞学院版html

二 什么是面向对象的程序设计及为何要有它

面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就比如精心设计好一条流水线,是一种机械式的思惟方式。java

优势是:复杂度的问题流程化,进而简单化(一个复杂的问题,分红一个个小的步骤去实现,实现小的步骤将会很是简单)python

缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线没法生产汽车,即使是能,也得是大改,改一个组件,牵一发而动全身。linux

应用场景:一旦完成基本不多改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。c++

 

面向对象的程序设计:核心是对象二字,(要理解对象为什么物,必须把本身当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也能够创造出来。面向对象的程序设计比如如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题须要四我的:唐僧,沙和尚,猪八戒,孙悟空,每一个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并很差玩,因而如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。而后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取),对象是特征与技能的结合体,基于面向对象设计程序就比如在创造一个世界,你就是这个世界的上帝,存在的皆为对象,不存在的也能够创造出来,与面向过程机械式的思惟方式造成鲜明对比,面向对象更加注重对现实世界的模拟,是一种“上帝式”的思惟方式。git

优势是:解决了程序的扩展性。对某一个对象单独修改,会马上反映到整个体系中,如对游戏中一我的物参数的特征和技能修改都很容易。程序员

缺点:算法

1. 编程的复杂度远高于面向过程,不了解面向对象而当即上手基于它设计程序,极容易出现过分设计的问题。一些扩展性要求低的场景使用面向对象会徒增编程难度,好比管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合。sql

2. 没法向面向过程的程序设计流水线式的能够很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即使是上帝也没法准确地预测最终结果。因而咱们常常看到对战类游戏,新增一个游戏人物,在对战的过程当中极容易出现阴霸的技能,一刀砍死3我的,这种状况是没法准确预知的,只有对象之间交互才能准确地知道最终的结果。

应用场景:需求常常变化的软件,通常需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方

面向对象的程序设计并非所有。对于一个软件质量来讲,面向对象的程序设计只是用来解决扩展性。

选读:程序设计思想发展史

三 类与对象

类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象类似的特征与技能的结合体

那么问题来了,先有的一个个具体存在的对象(好比一个具体存在的人),仍是先有的人类这个概念,这个问题须要分两种状况去看

在现实世界中:先有对象,再有类

世界上确定是先出现各类各样的实际存在的物体,而后随着人类文明的发展,人类站在不一样的角度总结出了不一样的种类,如人类、动物类、植物类等概念

也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在

在程序中:务必保证先定义类,后产生对象

这与函数的使用是相似的,先定义函数,后调用函数,类也是同样的,在程序中须要先定义类,后调用类

不同的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象

 

按照上述步骤,咱们来定义一个类(咱们站在老男孩学校的角度去看,在座的各位都是学生)

#在现实世界中,站在老男孩学校的角度:先有对象,再有类
对象1:李坦克
    特征:
        学校=oldboy
        姓名=李坦克
        性别=男
        年龄=18
    技能:
        学习
        吃饭
        睡觉

对象2:王大炮
    特征:
        学校=oldboy
        姓名=王大炮
        性别=女
        年龄=38
    技能:
        学习
        吃饭
        睡觉

对象3:牛榴弹
    特征:
        学校=oldboy
        姓名=牛榴弹
        性别=男
        年龄=78
    技能:
        学习
        吃饭
        睡觉


现实中的老男孩学生类
    类似的特征:
        学校=oldboy
    类似的技能:
        学习
        吃饭
        睡觉
在现实世界中:先有对象,再有类
#在程序中,务必保证:先定义(类),后使用(产生对象)
PS:
  1. 在程序中特征用变量标识,技能用函数标识
  2. 于是类中最多见的无非是:变量和函数的定义

#程序中的类
class OldboyStudent:
    school='oldboy'
    def learn(self):
        print('is learning')

    def eat(self):
        print('is eating')

    def sleep(self):
        print('is sleeping')



#注意:
  1.类中能够有任意python代码,这些代码在类定义阶段便会执行
  2.于是会产生新的名称空间,用来存放类的变量名与函数名,能够经过OldboyStudent.__dict__查看
  3.对于经典类来讲咱们能够经过该字典操做类名称空间的名字(新式类有限制),但python为咱们提供专门的.语法
  4.点是访问属性的语法,类中定义的名字,都是类的属性

#程序中类的用法
.:专门用来访问属性,本质操做的就是__dict__
OldboyStudent.school #等于经典类的操做OldboyStudent.__dict__['school']
OldboyStudent.school='Oldboy' #等于经典类的操做OldboyStudent.__dict__['school']='Oldboy'
OldboyStudent.x=1 #等于经典类的操做OldboyStudent.__dict__['x']=1
del OldboyStudent.x #等于经典类的操做OldboyStudent.__dict__.pop('x')


#程序中的对象
#调用类,或称为实例化,获得对象
s1=OldboyStudent()
s2=OldboyStudent()
s3=OldboyStudent()

#如此,s一、s二、s3都同样了,而这三者除了类似的属性以外还各类不一样的属性,这就用到了__init__
#注意:该方法是在对象产生以后才会执行,只用来为对象进行初始化操做,能够有任意代码,但必定不能有返回值
class OldboyStudent:
    ......
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    ......


s1=OldboyStudent('李坦克','',18) #先调用类产生空对象s1,而后调用OldboyStudent.__init__(s1,'李坦克','男',18)
s2=OldboyStudent('王大炮','',38)
s3=OldboyStudent('牛榴弹','',78)


#程序中对象的用法
#执行__init__,s1.name='牛榴弹',很明显也会产生对象的名称空间
s2.__dict__
{'name': '王大炮', 'age': '', 'sex': 38}

s2.name #s2.__dict__['name']
s2.name='王三炮' #s2.__dict__['name']='王三炮'
s2.course='python' #s2.__dict__['course']='python'
del s2.course #s2.__dict__.pop('course')
在程序中:先定义类,后产生对象

 !!!细说__init__方法!!!

#方式1、为对象初始化本身独有的特征
class People:
    country='China'
    x=1
    def run(self):
        print('----->', self)

# 实例化出三个空对象
obj1=People()
obj2=People()
obj3=People()

# 为对象定制本身独有的特征
obj1.name='egon'
obj1.age=18
obj1.sex='male'

obj2.name='lxx'
obj2.age=38
obj2.sex='female'

obj3.name='alex'
obj3.age=38
obj3.sex='female'

# print(obj1.__dict__)
# print(obj2.__dict__)
# print(obj3.__dict__)
# print(People.__dict__)





#方式2、为对象初始化本身独有的特征
class People:
    country='China'
    x=1
    def run(self):
        print('----->', self)

# 实例化出三个空对象
obj1=People()
obj2=People()
obj3=People()

# 为对象定制本身独有的特征
def chu_shi_hua(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
    obj.name = x
    obj.age = y
    obj.sex = z

chu_shi_hua(obj1,'egon',18,'male')
chu_shi_hua(obj2,'lxx',38,'female')
chu_shi_hua(obj3,'alex',38,'female')





#方式3、为对象初始化本身独有的特征
class People:
    country='China'
    x=1

    def chu_shi_hua(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
        obj.name = x
        obj.age = y
        obj.sex = z

    def run(self):
        print('----->', self)


obj1=People()
# print(People.chu_shi_hua)
People.chu_shi_hua(obj1,'egon',18,'male')

obj2=People()
People.chu_shi_hua(obj2,'lxx',38,'female')

obj3=People()
People.chu_shi_hua(obj3,'alex',38,'female')




# 方式4、为对象初始化本身独有的特征
class People:
    country='China'
    x=1

    def __init__(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
        obj.name = x
        obj.age = y
        obj.sex = z

    def run(self):
        print('----->', self)

obj1=People('egon',18,'male') #People.__init__(obj1,'egon',18,'male')
obj2=People('lxx',38,'female') #People.__init__(obj2,'lxx',38,'female')
obj3=People('alex',38,'female') #People.__init__(obj3,'alex',38,'female')


# __init__方法
# 强调:
#   一、该方法内能够有任意的python代码
#   二、必定不能有返回值
class People:
    country='China'
    x=1

    def __init__(obj, name, age, sex): #obj=obj1,x='egon',y=18,z='male'
        # if type(name) is not str:
        #     raise TypeError('名字必须是字符串类型')
        obj.name = name
        obj.age = age
        obj.sex = sex


    def run(self):
        print('----->', self)


# obj1=People('egon',18,'male')
obj1=People(3537,18,'male')

# print(obj1.run)
# obj1.run() #People.run(obj1)
# print(People.run)
!!!__init__方法之为对象定制本身独有的特征

PS:

1. 站的角度不一样,定义出的类是大相径庭的,详见面向对象实战之需求分析

2. 现实中的类并不彻底等于程序中的类,好比现实中的公司类,在程序中有时须要拆分红部门类,业务类...... 

3. 有时为了编程需求,程序中也可能会定义现实中不存在的类,好比策略类,现实中并不存在,可是在程序中倒是一个很常见的类

#python为类内置的特殊属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类全部父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)
类的特殊属性(了解便可)

!!!补充说明:从代码级别看面向对象 !!!

#一、在没有学习类这个概念时,数据与功能是分离的
def exc1(host,port,db,charset):
    conn=connect(host,port,db,charset)
    conn.execute(sql)
    return xxx


def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    conn.call_proc(sql)
    return xxx

#每次调用都须要重复传入一堆参数
exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')
exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')




#二、咱们能想到的解决方法是,把这些变量都定义成全局变量
HOST=‘127.0.0.1’
PORT=3306
DB=‘db1’
CHARSET=‘utf8’

def exc1(host,port,db,charset):
    conn=connect(host,port,db,charset)
    conn.execute(sql)
    return xxx


def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    conn.call_proc(sql)
    return xxx

exc1(HOST,PORT,DB,CHARSET,'select * from tb1;')
exc2(HOST,PORT,DB,CHARSET,'存储过程的名字')


#三、可是2的解决方法也是有问题的,按照2的思路,咱们将会定义一大堆全局变量,这些全局变量并无作任何区分,即可以被全部功能使用,然而事实上只有HOST,PORT,DB,CHARSET是给exc1和exc2这两个功能用的。言外之意:咱们必须找出一种可以将数据与操做数据的方法组合到一块儿的解决方法,这就是咱们说的类了

class MySQLHandler:
    def __init__(self,host,port,db,charset='utf8'):
        self.host=host
        self.port=port
        self.db=db
        self.charset=charset
    def exc1(self,sql):
        conn=connect(self.host,self.port,self.db,self.charset)
        res=conn.execute(sql)
        return res


    def exc2(self,sql):
        conn=connect(self.host,self.port,self.db,self.charset)
        res=conn.call_proc(sql)
        return res


obj=MySQLHandler('127.0.0.1',3306,'db1')
obj.exc1('select * from tb1;')
obj.exc2('存储过程的名字')


#改进
class MySQLHandler:
    def __init__(self,host,port,db,charset='utf8'):
        self.host=host
        self.port=port
        self.db=db
        self.charset=charset
        self.conn=connect(self.host,self.port,self.db,self.charset)
    def exc1(self,sql):
        return self.conn.execute(sql)

    def exc2(self,sql):
        return self.conn.call_proc(sql)


obj=MySQLHandler('127.0.0.1',3306,'db1')
obj.exc1('select * from tb1;')
obj.exc2('存储过程的名字')
数据与专门操做该数据的功能组合到一块儿

四 属性查找

类有两种属性:数据属性和函数属性

1. 类的数据属性是全部对象共享的

2. 类的函数属性是绑定给对象用的

#类的数据属性是全部对象共享的,id都同样
print(id(OldboyStudent.school))

print(id(s1.school))
print(id(s2.school))
print(id(s3.school))

'''
4377347328
4377347328
4377347328
4377347328
'''



#类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不同
#ps:id是python的实现机制,并不能真实反映内存地址,若是有内存地址,仍是之内存地址为准
print(OldboyStudent.learn)
print(s1.learn)
print(s2.learn)
print(s3.learn)
'''
<function OldboyStudent.learn at 0x1021329d8>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x1021466d8>>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146710>>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146748>>
'''
View Code

在obj.name会先从obj本身的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常  

练习:编写一个学生类,产生一堆学生对象,要求有一个计数器(属性),统计总共实例了多少个对象 

五 绑定到对象的方法的特殊之处

复制代码
#改写
class OldboyStudent:
    school='oldboy'
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def learn(self):
        print('%s is learning' %self.name) #新增self.name

    def eat(self):
        print('%s is eating' %self.name)

    def sleep(self):
        print('%s is sleeping' %self.name)


s1=OldboyStudent('李坦克','',18)
s2=OldboyStudent('王大炮','',38)
s3=OldboyStudent('牛榴弹','',78)
复制代码

 

类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可使用,但必须遵循函数的参数规则,有几个参数须要传几个参数

OldboyStudent.learn(s1) #李坦克 is learning
OldboyStudent.learn(s2) #王大炮 is learning
OldboyStudent.learn(s3) #牛榴弹 is learning

类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,并且是绑定到对象的,虽然全部对象指向的都是相同的功能,可是绑定到不一样的对象就是不一样的绑定方法

强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’自己当作第一个参数传给方法,即自动传值(方法__init__也是同样的道理)

s1.learn() #等同于OldboyStudent.learn(s1)
s2.learn() #等同于OldboyStudent.learn(s2)
s3.learn() #等同于OldboyStudent.learn(s3)

注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self能够是任意名字,可是约定俗成地写出self。

 

类即类型

  提示:python的class术语与c++有必定区别,与 Modula-3更像。

  python中一切皆为对象,且python3中类与类型是一个概念,类型就是类

复制代码
#类型dict就是类dict
>>> list
<class 'list'>

#实例化的到3个对象l1,l2,l3
>>> l1=list()
>>> l2=list()
>>> l3=list()

#三个对象都有绑定方法append,是相同的功能,但内存地址不一样
>>> l1.append
<built-in method append of list object at 0x10b482b48>
>>> l2.append
<built-in method append of list object at 0x10b482b88>
>>> l3.append
<built-in method append of list object at 0x10b482bc8>

#操做绑定方法l1.append(3),就是在往l1添加3,绝对不会将3添加到l2或l3
>>> l1.append(3)
>>> l1
[3]
>>> l2
[]
>>> l3
[]
#调用类list.append(l3,111)等同于l3.append(111)
>>> list.append(l3,111) #l3.append(111)
>>> l3
[111] 
复制代码

六 对象之间的交互

复制代码
class Garen:        #定义英雄盖伦的类,不一样的玩家能够用它实例出本身英雄;
    camp='Demacia'  #全部玩家的英雄(盖伦)的阵营都是Demacia;
    def __init__(self,nickname,aggressivity=58,life_value=455): #英雄的初始攻击力58...;
        self.nickname=nickname  #为本身的盖伦起个别名;
        self.aggressivity=aggressivity #英雄都有本身的攻击力;
        self.life_value=life_value #英雄都有本身的生命值;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据本身的攻击力,攻击敌人就减掉敌人的生命值。
复制代码

咱们能够仿照garen类再建立一个Riven类

复制代码
class Riven:
    camp='Noxus'  #全部玩家的英雄(锐雯)的阵营都是Noxus;
    def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻击力54;
        self.nickname=nickname  #为本身的锐雯起个别名;
        self.aggressivity=aggressivity #英雄都有本身的攻击力;
        self.life_value=life_value #英雄都有本身的生命值;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据本身的攻击力,攻击敌人就减掉敌人的生命值。 
复制代码

实例出俩英雄

>>> g1=Garen('草丛伦')
>>> r1=Riven('锐雯雯')

交互:锐雯雯攻击草丛伦,反之同样

>>> g1.life_value
455
>>> r1.attack(g1)
>>> g1.life_value
401 

补充:

  garen_hero.Q()称为向garen_hero这个对象发送了一条消息,让他去执行Q这个功能,相似的有:

  garen_hero.W()

  garen_hero.E()

  garen_hero.R()

七 练习

连接:http://www.cnblogs.com/linhaifeng/articles/7340497.html

八 继承与派生

连接:http://www.cnblogs.com/linhaifeng/articles/7340153.html

九 多态与多态性

连接:http://www.cnblogs.com/linhaifeng/articles/7340687.html

十 封装

连接:http://www.cnblogs.com/linhaifeng/articles/7340801.html

十二 小白容易犯的错误

1.面向对象的程序设计看起来高大上,因此我在编程时就应该保证通篇class,这样写出的程序必定是好的程序(面向对象只适合那些可扩展性要求比较高的场景)

2.不少人喜欢说面向对象三大特性(这是从哪传出来的,封装,多态,继承?漏洞太多太多,好吧暂且称为三大特性),那么我在基于面向对象编程时,我必定要让我定义的类中完整的包含这三种特性,这样写确定是好的程序

好家伙,我说降龙十八掌有十八掌,那么你每次跟人干仗都要从第一掌打到第18掌这才显得你会了是么:面对敌人,你打到第三掌对方就已经倒下了,你说,不行,你给老子起来,老子尚未show完...

3.类有类属性,实例有实例属性,因此咱们在定义class时必定要定义出那么几个类属性,想不到怎么办,那就使劲的想,定义的越多越牛逼

这就犯了一个严重的错误,程序越早面向对象,死的越早,为啥面向对象,由于咱们要将数据与功能结合到一块儿,程序总体的结构都没有出来,或者说须要考虑的问题你都没有搞清楚个八九不离十,你就开始面向对象了,这就致使了,你在那里干想,自觉得想通了,定义了一堆属性,结果后来又都用不到,或者想不通到底应该定义啥,那就一直想吧,想着想着就疯了。

你见过哪家公司要开发一个软件,上来就开始写,确定是频繁的开会讨论计划,请看第八节

4.既然这么麻烦,那么我完全解脱了,咱们不要用面向对象编程了,你啊,你有大才,你能成事啊,傻叉。

十三 python中关于OOP的经常使用术语

抽象/实现

抽象指对现实世界问题和实体的本质表现,行为和特征建模,创建一个相关的子集,能够用于 绘程序结构,从而实现这种模型。抽象不只包括这种模型的数据属性,还定义了这些数据的接口。

对某种抽象的实现就是对此数据及与之相关接口的现实化(realization)。现实化这个过程对于客户 程序应当是透明并且无关的。 

封装/接口

封装描述了对数据/信息进行隐藏的观念,它对数据属性提供接口和访问函数。经过任何客户端直接对数据的访问,无视接口,与封装性都是背道而驰的,除非程序员容许这些操做。做为实现的 一部分,客户端根本就不须要知道在封装以后,数据属性是如何组织的。在Python中,全部的类属性都是公开的,但名字可能被“混淆”了,以阻止未经受权的访问,但仅此而已,再没有其余预防措施了。这就须要在设计时,对数据提供相应的接口,以避免客户程序经过不规范的操做来存取封装的数据属性。

注意:封装毫不是等于“把不想让别人看到、之后可能修改的东西用private隐藏起来”

真正的封装是,通过深刻的思考,作出良好的抽象,给出“完整且最小”的接口,并使得内部细节能够对外透明

(注意:对外透明的意思是外部调用者能够顺利的获得本身想要的任何功能,彻底意识不到内部细节的存在)

合成

合成扩充了对类的 述,使得多个不一样的类合成为一个大的类,来解决现实问题。合成 述了 一个异常复杂的系统,好比一个类由其它类组成,更小的组件也多是其它的类,数据属性及行为, 全部这些合在一块儿,彼此是“有一个”的关系。

派生/继承/继承结构

派生描述了子类衍生出新的特性,新类保留已存类类型中全部须要的数据和行为,但容许修改或者其它的自定义操做,都不会修改原类的定义。
继承描述了子类属性从祖先类继承这样一种方式
继承结构表示多“代”派生,能够述成一个“族谱”,连续的子类,与祖先类都有关系。

泛化/特化

基于继承
泛化表示全部子类与其父类及祖先类有同样的特色。
特化描述全部子类的自定义,也就是,什么属性让它与其祖先类不一样。

多态与多态性

多态指的是同一种事物的多种状态:水这种事物有多种不一样的状态:冰,水蒸气

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

冰,水蒸气,都继承于水,它们都有一个同名的方法就是变成云,可是冰.变云(),与水蒸气.变云()是大相径庭的过程,虽然调用的方法都同样

自省/反射

自省也称做反射,这个性质展现了某对象是如何在运行期取得自身信息的。若是传一个对象给你,你能够查出它有什么能力,这是一项强大的特性。若是Python不支持某种形式的自省功能,dir和type内建函数,将很难正常工做。还有那些特殊属性,像__dict__,__name__及__doc__

 

十四 面向对象的软件开发

    不少人在学完了python的class机制以后,遇到一个生产中的问题,仍是会懵逼,这其实太正常了,由于任何程序的开发都是先设计后编程,python的class机制只不过是一种编程方式,若是你硬要拿着class去和你的问题死磕,变得更加懵逼都是分分钟的事,在之前,软件的开发相对简单,从任务的分析到编写程序,再到程序的调试,能够由一我的或一个小组去完成。可是随着软件规模的迅速增大,软件任意面临的问题十分复杂,须要考虑的因素太多,在一个软件中所产生的错误和隐藏的错误、未知的错误可能达到惊人的程度,这也不是在设计阶段就彻底解决的。

    因此软件的开发其实一整套规范,咱们所学的只是其中的一小部分,一个完整的开发过程,须要明确每一个阶段的任务,在保证一个阶段正确的前提下再进行下一个阶段的工做,称之为软件工程

    面向对象的软件工程包括下面几个部:

1.面向对象分析(object oriented analysis ,OOA)

    软件工程中的系统分析阶段,要求分析员和用户结合在一块儿,对用户的需求作出精确的分析和明确的表述,从大的方面解析软件系统应该作什么,而不是怎么去作。面向对象的分析要按照面向对象的概念和方法,在对任务的分析中,从客观存在的事物和事物之间的关系,贵南出有关的对象(对象的‘特征’和‘技能’)以及对象之间的联系,并将具备相同属性和行为的对象用一个类class来标识。

    创建一个能反映这是工做状况的需求模型,此时的模型是粗略的。

2 面向对象设计(object oriented design,OOD)

    根据面向对象分析阶段造成的需求模型,对每一部分分别进行具体的设计。

    首先是类的设计,类的设计可能包含多个层次(利用继承与派生机制)。而后以这些类为基础提出程序设计的思路和方法,包括对算法的设计。

    在设计阶段并不牵涉任何一门具体的计算机语言,而是用一种更通用的描述工具(如伪代码或流程图)来描述

3 面向对象编程(object oriented programming,OOP)

    根据面向对象设计的结果,选择一种计算机语言把它写成程序,能够是python

4 面向对象测试(object oriented test,OOT)

    在写好程序后交给用户使用前,必须对程序进行严格的测试,测试的目的是发现程序中的错误并修正它。

    面向对的测试是用面向对象的方法进行测试,以类做为测试的基本单元。

5 面向对象维护(object oriendted soft maintenance,OOSM)

    正如对任何产品都须要进行售后服务和维护同样,软件在使用时也会出现一些问题,或者软件商想改进软件的性能,这就须要修改程序。

    因为使用了面向对象的方法开发程序,使用程序的维护比较容易。

    由于对象的封装性,修改一个对象对其余的对象影响很小,利用面向对象的方法维护程序,大大提升了软件维护的效率,可扩展性高。

 

    在面向对象方法中,最先发展的确定是面向对象编程(OOP),那时OOA和OOD都尚未发展起来,所以程序设计者为了写出面向对象的程序,还必须深刻到分析和设计领域,尤为是设计领域,那时的OOP实际上包含了如今的OOD和OOP两个阶段,这对程序设计者要求比较高,许多人感到很难掌握。

    如今设计一个大的软件,是严格按照面向对象软件工程的5个阶段进行的,这个5个阶段的工做不是由一我的从头至尾完成的,而是由不一样的人分别完成,这样OOP阶段的任务就比较简单了。程序编写者只须要根据OOd提出的思路,用面向对象语言编写出程序既可。

十五 面向对象实战

连接:http://www.cnblogs.com/linhaifeng/articles/7341318.html

 

本周做业

角色:学校、学员、课程、讲师
要求:
1. 建立北京、上海 2 所学校
2. 建立linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
3. 课程包含,周期,价格,经过学校建立课程 
4. 经过学校建立班级, 班级关联课程、讲师
5. 建立学员时,选择学校,关联班级
5. 建立讲师角色时要关联学校, 
6. 提供两个角色接口
6.1 学员视图, 能够注册, 交学费, 选择班级,
6.2 讲师视图, 讲师可管理本身的班级, 上课时选择班级, 查看班级学员列表 , 修改所管理的学员的成绩 
6.3 管理视图,建立讲师, 建立班级,建立课程

7. 上面的操做产生的数据都经过pickle序列化保存到文件里

相关文章
相关标签/搜索