• 第五章:5.2面向对象-绑定方法和非绑定方法| 内置方法 |元类


    5、绑定方法与非绑定方法

    在类内部定义的函数,分为两大类:
    一:绑定方法:绑定给谁,就应该由谁来调用,谁来调用就会把调用者当作第一个参数自动传入
      绑定到对象的方法:在类内定义的没有被任何装饰器修饰的,会把自己当做第一个参数传进去;

      绑定到类的方法:在类内定义的被装饰器classmethod修饰的方法。

    二:非绑定方法:没有自动传值这么一说了,就类中定义的一个普通工具,对象和类都可以使用调用
      非绑定方法:不与类或者对象绑定;

    #####绑定到对象
    class Foo:
        def __init__(self,name):
            self.name = name
        def tell(self):   #绑定到对象的方法;类内部定义的函数就是给对象使用的
            print('名字是%s'%self.name)
    f = Foo('egon')
    #print(Foo.tell)  #<function Foo.tell at 0x000000000299CB70>   类访问自己内部函数属性的时候,它就是一个普通函数,没有自动传值一说
    #Foo.tell(f)      #名字是egon                                   类非要用,就要给它传值
    # print(f.tell)   #<bound method Foo.tell of <__main__.Foo object at 0x00000000027BF630>> 绑定方法指向类的那个函数,跟类使用的是一个功能。  
    
    f.tell()        #名字是egon                                  绑定给谁就由谁来调用,就会把调用者当做第一个参数自动传进去;
    #####绑定到类
    class Foo:
        def __init__(self,name):
            self.name = name
        def tell(self):
            print('名字是%s'%self.name)
        @classmethod   ###绑定到类的方法
        def func(cls): #绑定到类,把类当做第一个参数传进去;cls=Foo
            print(cls)
    
    print(Foo.func) #<bound method Foo.func of <class '__main__.Foo'>>  加了装饰器后,定义成绑定到类的方法而不是函数了
    Foo.func()      #<class '__main__.Foo'>
    ######非绑定方法,没有自动传值了
    class Foo:
        def __init__(self,name):
            self.name = name
        def tell(self):
            print('名字是%s'%self.name)
        @classmethod
        def func(cls): #绑定到类,把类当做第一个参数传进去;
            print(cls)
        @staticmethod  #这才被认为一个真正意义上的函数,没有自动传值了。非绑定方法加个@staticmethod
        def func1(x,y):
            print(x+y)
    
    f = Foo('egon')
    f.func()         #<class '__main__.Foo'>
    print(Foo.func1) #<function Foo.func1 at 0x000000000296CC80>  类 都是普通函数
    print(f.func1)   #<function Foo.func1 at 0x000000000296CC80>  对象 普通函数
    
    Foo.func1(1,2)  #3  类来调用
    f.func1(2,4)    #6  对象来调用

    在类内部定义的函数分为两大类:绑定方法和非绑定方法(就是普通函数)。

    使用场景

    根据函数体的逻辑想传什么参数

    class People:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
        def tell_info(self): #绑定到对象的方法
            print('Name:%s Age:%s Sex:%s'%(self.name,self.age,self.sex))
    p = People('egon',18,'male')
    #绑定给对象,就应该由对象来调用,自动将对象本身当做第一个参数传入
    p.tell_info() #tell_info(p) # Name:egon Age:18 Sex:male
    import settings  #写一个配置文件  name = 'alex'  age = 18  sex = male
    class People:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
        def tell_info(self): #绑定到对象的方法
            print('Name:%s Age:%s Sex:%s'%(self.name,self.age,self.sex))
        @classmethod
        def from_conf(cls):   #不能写死,需要写个参数把类传进去
            obj = cls(
                settings.name,
                settings.age,
                settings.sex
            )
            return obj
    #绑定给类,就应该由类来调用,自动将类本身当做第一个参数传入
    p = People.from_conf() #本质上就是from_conf(People)  #从配置文件里边读取配置进行实例化
    p.tell_info()         #Name:alex Age:18 Sex:male
    import settings
    import hashlib
    import time
    class People:
        def __init__(self,name,age,sex):
            self.id = self.creat_id()  #需要传参数就传
            self.name = name
            self.age = age
            self.sex = sex
        def tell_info(self): #绑定到对象的方法
            print('Name:%s Age:%s Sex:%s'%(self.name,self.age,self.sex))
        @classmethod
        def from_conf(cls):
            obj = cls(
                settings.name,
                settings.age,
                settings.sex
            )
            return obj
    #非绑定方法,不与类或者对象绑定,谁都可以调用,没有自动传值一说
        @staticmethod
        def creat_id():  #不依赖类和对象传入参数
            m=hashlib.md5(str(time.time()).encode('utf-8'))
            return m.hexdigest()
    p1=People('egon1',18,'male')
    p2=People('egon2',28,'male')
    p3=People('egon3',38,'male')
    print(p1.create_id()) #66c0399486670e0faaab1324e98b33b0
    print(p2.id)          #66c0399486670e0faaab1324e98b33b0
    print(p3.id)          #66c0399486670e0faaab1324e98b33b0

    6、反射

    通过字符串来映射到一个对象的属性

    class People:
        country='China'
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def talk(self):
            print('%s is talking' %self.name)
    obj=People('egon',18)
    # print(obj.name)   #obj.__dict__['name'] #.后面是个属性,而不是字符串;用户通过字符串来映射到一个对象的属性身上
    # print(obj.talk)   #<bound method People.talk of <__main__.People object at 0x00000000027DFB00>>
    # choice=input('>>: ') #choice='name'
    # print(obj.choice) #会报错 print(obj.'name')
    
    #判断有没有这个属性
    print(hasattr(obj,'name'))  #True  obj.name #obj.__dict__['name']
    print(hasattr(obj,'talk'))  #True  obj.talk
    #拿到对象的属性 ,没有就报错
    print(getattr(obj,'name'))        # egon
    print(getattr(obj,'namexx',None)) # None
    print(gatattr(obj,'talk')) #<bound method People.talk of <__main__.People object at 0x0000000002961F28>>
    #修改 或新增 setattr(obj,'sex','male') #obj.sex = 'male' print(obj.sex) # male #删除 delattr(obj,'age') # del obj.age print(obj.__dict__) # {'name': 'egon', 'sex': 'male'} #类同样适用以上方法 print(getattr(People,'country')) #People.country #China
    ####反射的应用:
    class Service:
        def run(self):
            while True:
                inp=input('>>: ').strip() #cmd='get a.txt'
                cmds=inp.split() #cmds=['get','a.txt']
                # print(cmds)
                if hasattr(self,cmds[0]): #判断有没有get这个方法
                    func=getattr(self,cmds[0]) #拿到它
                    func(cmds)  #执行
        def get(self,cmds):
            print('get.......',cmds)
        def put(self,cmds):
            print('put.......',cmds)
    obj=Service()
    obj.run()

    7、内置方法

    http://www.cnblogs.com/linhaifeng/articles/6204014.html

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象,判断谁是谁的实例;

    issubclass(sub, super)检查sub类是否是 super 类的派生类

    只要是__开头__结尾的方法都不要直接去用,python会自动调用的,什么情况下会触发呢?

    ####item系列 #把对象模拟成像字典样
    ###获取
    class Foo: #Dict
        def __init__(self,name):
            self.name=name
        def __getitem__(self, item): #要知道item获取的什么值 #item='name',把name传进去;我通过字符串怎么访问属性呢,可以用反射,也可以self.__dict__(item)
            print('getitem...')
            print(item)
            return self.__dict__.get(item) #这样就取到值了;通过字典的key取它的value  ##有就取值,没有就不会报错了
        def __setitem__(self, key, value):
            print('setitem...')
            print(key,value)
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('delitem...')
            print(key)
            del self.__dict__[key]
    obj=Foo('egon')      ##把obj模拟成字典的样子
    print(obj.__dict__)  #{'name': 'egon'}
    ###查看属性
    #obj.属性名 #原来是这样获取的
    #obj['name']          #打印出:getitem...  name        obj.name想要完成这样一个取值,应该让那个方法有个返回值;按照这种形式一打开它就会触发__getitem__来取值
    #print(obj['name']    #打印出:getitem...  name    egon
    print(obj['namexx'])  #打印出:getitem...  namexx  None    obj.name
    class Foo: #Dict
        def __init__(self,name):
            self.name=name
        def __getitem__(self, item): #要知道item获取的什么值 #item='name'
            print('getitem...')
            print(item)
            return self.__dict__.get(item) #通过字典的key取它的value #有就取值,没有就不会报错了
        def __setitem__(self, key, value): #value就是要设置的值
            #print('setitem...')
            #print(key,value)
            self.__dict__[key]=value  #这样就完成了真正的设置,上边两步就可以去掉了
        def __delitem__(self, key):
            print('delitem...')
            print(key)
            del self.__dict__[key]
    obj=Foo('egon')
    #print(obj.__dict__)
    
    #设置属性
    #obj.sex = 'male' 
    obj['sex'] = 'male' #会触发__setitem__,并且打印key,value
    print(obj.__dict__) #验证下,设置成功了  #{'name': 'egon', 'sex': 'male'}
    print(obj.sex)      #获取 male
    class Foo: #Dict
        def __init__(self,name):
            self.name=name
        def __getitem__(self, item): #要知道item获取的什么值 #item='name'
            #print('getitem...')
            #print(item)
            return self.__dict__.get(item) #通过字典的key取它的value #有就取值,没有就不会报错了
        def __setitem__(self, key, value):
            #print('setitem...')
            #print(key,value)
            self.__dict__[key]=value  #这样就完成了真正的设置,上边两步就可以去掉了
        def __delitem__(self, key):
            #print('delitem...')
            #print(key)
            del self.__dict__[key]  ##完成真正的删除
    obj=Foo('egon')
    #print(obj.__dict__)
    #查看属性
    #obj.属性名 #原来是这样获取的
    #obj['name'] #obj.name 想要完成这样一个取值,应该让那个方法有个返回值;一打开它就会触发__getitem__来取值
    #print(obj['namexx'])  #obj.name
    
    #设置属性
    #obj.sex = 'male'
    # obj['sex'] = 'male' #会触发__setitem__,并且打印key,value
    # print(obj.__dict__) #验证下,设置成功了
    # print(obj.sex) #获取
    
    #删除属性
    #del obj.name
    del obj['name']
    print(obj.__dict__)  #delitem...  name  {}
    #########__str__方法: 
    # d=dict({'name':'egon'})
    # print(isinstance(d,dict)) #True
    # print(d)                 #{'name','egon'} #打印成有用的东西,而不是打印成内存地址
    
    class People:
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def __str__(self):  #__str__定义完之后,会在打印对象的时候会触发对象下的__str__方法,然后把返回字符串类型的结果打印出
            print('====>str')
            return '<name:%s,age:%s>' %(self.name,self.age)  #要返回一个字符串类型
    obj=People('egon',18)
    print(obj) #打印出:====>str  <name:egon,age:18>   ;res=obj.__str__()  #一打印的时候就会触发 obj.__str__()这个方法,把它的结果拿到打印
    ####__del__  回收资源的
    # f=open('settings.py')
    # f.read()
    # f.close() #回收操作系统的资源 ,执行它后f这个变量还存在
    
    # print(f)  #<_io.TextIOWrapper name='settings.py' mode='r' encoding='cp936'>
    # f.read()
    
    class Open:
        def __init__(self,filename):
            print('open file.......') #给操作系统发一个请求
            self.filename=filename
        def __del__(self):   ##在对象被删除的时候会先触发这个方法的执行再删除。 程序运行完之后py会自动给你删对象,在删对象之前先触发这个方法的执行;
        print('回收操作系统资源:self.close()')  #py只会帮你回收对象本身,并不会给你回收对象相关的属性,这时候就可以写在这里了使用__del__
    f=Open('settings.py') #它是一个变量,占应用程序的一个内存 
    #del f #del f 如果运行这一步是程序先运行打开文件,然后回收操作系统资源,最后执行完程序。 #同样也会触发它 f.__del__() 
    print('----main------') ##代表程序执行完了会自动触发del f的执行; 但遗留下操作系统的资源。

     8、元类介绍

    exec:三个参数
    
    参数一:字符串形式的命令
    
    参数二:全局作用域(字典形式),如果不指定,默认为globals()
    
    参数三:局部作用域(字典形式),如果不指定,默认为locals()
    g={
        'x':1,
        'y':2
    }
    l={}
    #可以把exec看做一个函数,g,l是指定全局和局部作用域
    exec("""
    global x,m
    x=10
    m=100
    z=3
    """,g,l)
    print(g)
    print(l)

    一切皆对象,对象可以怎么用?
    1、都可以被引用,x=obj
    2、都可以当作函数的参数传入
    3、都可以当作函数的返回值
    4、都可以当作容器类的元素,l=[func,time,obj,1]

    ##类也是对象,Foo=type(....) 看做type传了个值进去
    class Foo:
        pass
    obj=Foo()
    print(type(obj)) #<class '__main__.Foo'>
    print(type(Foo)) #<class 'type'>
    
    class Bar:
        pass
    print(type(Bar)) #查看类型 #<class 'type'>
    ##产生类的类称之为元类,默认所以用class定义的类,他们的元类是type

      元类是类的类,是类的模板

    元类是用来控制如何创建类的,正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为

    元类的实例化的结果为我们用class定义的类,正如类的实例为对象(f1对象是Foo类的一个实例,Foo类是 type 类的一个实例)

    type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象.

    定义类的两种方式:

    #定义类的两种方式:
    #方式一:使用class关键字
    class Chinese: #Chinese=type(...)
        country='China'
        def __init__(self,namem,age):
            self.name=namem
            self.age=age
        def talk(self):
            print('%s is talking' %self.name)
    # print(Chinese)
    obj=Chinese('egon',18)
    print(obj,obj.name,obj.age)
    
    
    #方式二:type  手动模拟class创建类的过程,将创建类的步骤拆分开,手动去创建。
    #定义类的三要素:类名,类的基类们,类的名称空间
    class_name='Chinese' #类名
    class_bases=(object,) #继承的基类;类的父类
    class_body="""       #类体
    country='China'
    def __init__(self,namem,age):
        self.name=namem
        self.age=age
    def talk(self):
        print('%s is talking' %self.name)
    """ 
    class_dic={} #放到字典里初始化为空      #应该把上边"""  """里边类体的代码执行一下得到的结果放到一个字典里边;
    exec(class_body,globals(),class_dic) 
    # print(class_dic)  #{'country': 'China', '__init__': <function __init__ at 0x00000000003D3E18>, 'talk': <function talk at 0x0000000001F1CAE8>}
    
    Chinese1=type(class_name,class_bases,class_dic) #得到一个元类 # print(Chinese1) #<class '__main__.Chinese'> obj1=Chinese1('egon',18) print(obj1,obj1.name,obj1.age) #<__main__.Chinese object at 0x00000000029619B0> egon 18

    步骤一(先处理类体->名称空间):类体定义的名字都会存放于类的名称空间中(一个局部的名称空间),我们可以事先定义一个空字典,然后用exec去执行类体的代码(exec产生名称空间的过程与真正的class过程类似,只是后者会将__开头的属性变形),生成类的局部名称空间,即填充字典

    步骤二:调用元类type(也可以自定义)来产生类Chinense 

    我们看到,type 接收三个参数:

    • 第 1 个参数是字符串 ‘Foo’,表示类名
    • 第 2 个参数是元组 (object, ),表示所有的父类
    • 第 3 个参数是字典,这里是一个空字典,表示没有定义属性和方法

    补充:若Foo类有继承,即class Foo(Bar):.... 则等同于type('Foo',(Bar,),{})

    自定义元类控制类的创建

    #一个类没有声明自己的元类,默认他的元类就是type,除了使用元类type,用户也可以通过继承type来自定义元类(顺便我们也可以瞅一瞅元类如何控制类的行为,工作流程是什么)
    #自定义元类控制类的行为
    class Mymeta(type):
        def __init__(self,class_name,class_bases,class_dic):  #可能覆盖父类;继承默认元类的一堆属性
            if not class_name.istitle():
                raise TypeError('类名的首字母必须大写') #会报错
            print(class_dic)  #{'__module__': '__main__', '__qualname__': 'Chinese', '__doc__': 'a
        中文人的类  ##注释写上之后才有__doc__属性
        ', 'country': 'China', '__init__': <function Chinese.__init__ at 0x000000000296CB70>, 'talk': <function Chinese.talk at 0x000000000296CBF8>}
            if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
                raise TypeError('必须有注释,且注释不能为空')
            super(Mymeta,self).__init__(class_name,class_bases,class_dic)  #你写__init__这个功能之前把父类的也重用了一遍
    class Chinese(object,metaclass=Mymeta):  #指定元类为Mymeta,这个类Chinese的创建行为就由你来控制了
        '''a
        中文人的类  ##注释写上之后才有__doc__属性
        '''
        country='China'
        def __init__(self,namem,age):
            self.name=namem
            self.age=age
        def talk(self):
            print('%s is talking' %self.name)
    # Chinese=Mymeta(class_name,class_bases,class_dic)  #在实例化,必须要有个__init__方法;触发Mymeta实例化的过程就会触发__init__方法的执行

    自定义元类控制类的实例化

    #知识储备__call__方法 #让对象变成可调用对象  
    class Foo:
        def __call__(self, *args, **kwargs):
            print(self)   #<__main__.Foo object at 0x0000000001DBB128>
            print(args)   #(1, 2, 3)
            print(kwargs) #{'a': 1, 'b': 2, 'c': 3}
    obj=Foo()  #obj之所以可以调用是因Foo里边有个__call__方法
    obj(1,2,3,a=1,b=2,c=3) #obj.__call__(obj,1,2,3,a=1,b=2,c=3)
    # #元类内部也应有有一个__call__方法,会在调用Foo时触发该方法的执行
    # #Foo(1,2,x=1)  #Foo.__call__(Foo,1,2,x=1)
    class Mymeta(type):
        def __init__(self,class_name,class_bases,class_dic):
            if not class_name.istitle():
                raise TypeError('类名的首字母必须大写')
            if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
                raise TypeError('必须有注释,且注释不能为空')
            super(Mymeta,self).__init__(class_name,class_bases,class_dic)
        def __call__(self, *args, **kwargs): #obj=Chinese('egon',age=18) #一个类实例化的行为就是__call__里边的内容
            # print(self) #self=Chinese
            # print(args) #args=('egon',)
            # print(kwargs) #kwargs={'age': 18}
            #之前学的是调用Chinese所要做的三件事情:  ##这其实就是__call__方法内部
            #第一件事:先造一个空对象obj
            obj=object.__new__(self)  #self= Chinese
            #第二件事:初始化obj
            self.__init__(obj,*args,**kwargs) #把空对象传进来,把参数传进来
            #第三件事:返回obj
            return obj
    class Chinese(object,metaclass=Mymeta):
        '''
        中文人的类
        '''
        country='China'
        def __init__(self,namem,age):
            self.name=namem
            self.age=age
        def talk(self):
            print('%s is talking' %self.name)
    obj=Chinese('egon',age=18) #Chinese.__call__(Chinese,'egon',18) 调用这个对象会触发它的类Mymeta,下面那个__call__
    
    print(obj.__dict__)  #{'name': 'egon', 'age': 18}

    应用

    #单例模式 对象内部特征是一样的话就不要产生空间,用一个空间就可以了,节省空间
    #实现方式一:
    class MySQL:
        __instance=None #__instance=obj1
        def __init__(self):
            self.host='127.0.0.1'
            self.port=3306
        @classmethod
        def singleton(cls):
            if not cls.__instance:
                obj=cls()
                cls.__instance=obj
            return cls.__instance
        def conn(self):
            pass
        def execute(self):
            pass
    # obj1=MySQL()
    # obj2=MySQL()
    # obj3=MySQL()
    # print(obj1)
    # print(obj2)
    # print(obj3)
    obj1=MySQL.singleton()
    obj2=MySQL.singleton()
    obj3=MySQL.singleton()
    print(obj1 is obj3)
    #实现方式二:元类的方式
    class Mymeta(type):
        def __init__(self,class_name,class_bases,class_dic):
            if not class_name.istitle():
                raise TypeError('类名的首字母必须大写')
            if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
                raise TypeError('必须有注释,且注释不能为空')
            super(Mymeta,self).__init__(class_name,class_bases,class_dic)
            self.__instance=None  #设置个属性
        def __call__(self, *args, **kwargs): #obj=Chinese('egon',age=18)
            if not self.__instance:  #没有__instance就给它造一个
                obj=object.__new__(self) #造一个空对象
                self.__init__(obj)  #self代表Mysql
                self.__instance=obj
            return self.__instance  #有就返回
    class Mysql(object,metaclass=Mymeta):
        '''
        Mysql xxx
        '''
        def __init__(self):
            self.host='127.0.0.1'
            self.port=3306
        def conn(self):
            pass
        def execute(self):
            pass
    obj1=Mysql()  #调用这个对象触发__call__下面的方法
    obj2=Mysql()
    obj3=Mysql()
    print(obj1 is obj2 is obj3)

    python中的__init__、__new__方法

    class TestCls():
        """docstring for TestCls"""
    
        def __init__(self, name):
            print('init')
            print(self)
            print(type(self))
            self.name = name
    
        def __new__(cls, name):
            print('new')
            print(cls)
            print(type(cls))
            return super().__new__(cls)
    
    c = TestCls("CooMark")
    
    # new...
    # <class '__main__.TestCls'>
    # <class 'type'>
    
    # init...
    # <__main__.TestCls object at 0x02201130>
    # <class '__main__.TestCls'>

    异同点


    1. 参数
      • __new__的第一个占位参数是class对象
      • __init__的第一个占位参数是class的实例对象
      • 其他的参数应一致
    2. 作用
      • __new__ 用来创建实例,在返回的实例上执行__init__,如果不返回实例那么__init__将不会执行
      • __init__ 用来初始化实例,设置属性什么的

    __new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。还有就是实现自定义的metaclass

    • 继承不可变class 

    假如我们需要一个永远都是正数的整数类型,通过集成int,我们可能会写出这样的代码

    class PositiveInteger(int):
    
        def __init__(self, value):
            super().__init__(self, abs(value))
    
    i = PositiveInteger(-3)
    print(i)
    # # TypeError: object.__init__() takes no parameters
    
    
    class PositiveInteger(int):
    
        def __new__(cls, value):
            return super(PositiveInteger, cls).__new__(cls, abs(value))
    i = PositiveInteger(-3)
    print(i)
    # 3
    • 用__new__来实现单例
    class Singleton(object):
        def __new__(cls):
            # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象
            if not hasattr(cls, 'instance'):
                cls.instance = super(Singleton, cls).__new__(cls)
            return cls.instance
    obj1 = Singleton()
    obj2 = Singleton()
    obj1.attr1 = 'value1'
    print( obj1.attr1, obj2.attr1)
    print( obj1 is obj2)

    参考:http://www.jb51.net/article/48044.htm

    __new__: 对象的创建,是一个静态方法,第一个参数是cls。(想想也是,不可能是self,对象还没创建,哪来的self)

    __init__ : 对象的初始化, 是一个实例方法,第一个参数是self。

    __call__ : 对象可call,注意不是类,是对象。

    先有创建,才有初始化。即先__new__,而后__init__。

        __call__方法  对象可call,注意不是类,是对象。

         当实现了这个方法时,这个类的实例(对象)可以当作函数一样调用。
      比如类A实现了__call__(self, x), 那么
      a = A()
      a(x) #把a当函数使

    面向对象的软件开发 

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

    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提出的思路,用面向对象语言编写出程序既可。

  • 相关阅读:
    String类之indexOf--->查找某字对应的位置
    5、文件过滤器
    String类之endsWith方法--->检测该字符串以xx为结尾
    for循环
    java-成员方法/变量、类方法/变量等区别
    4、File类之获取方法
    3、File类之创建、删除、重命名、判断方法
    2、创建File类对象
    Java 实现Redis客户端,服务端
    Phoenix踩坑填坑记录
  • 原文地址:https://www.cnblogs.com/shengyang17/p/9196995.html
Copyright © 2020-2023  润新知