zoukankan      html  css  js  c++  java
  • day08 面向对象补充及单例模式

    一、面向对象中的静态字段和普通字段

    静态字段、和普通字段
    使用规范:
    普通字段只能用对象访问
    静态字段用类来访问 (在Python中静态字段可以用对象访问也可以用类访问,但在其他语言中只能用类来访问静态字段,而且为防止在某种情况下报错,在使用静态字段时需用类来访问)
    class Province:
        country = 'China'  # 静态字段     静态字段是属于类的       当有无数个对象时,没个对象都有一个同样的字段,这样的话会浪费内存,所以设定一个静态字段,只需在内存里创建一次即可
    
        def __init__(self, name):
            self.name = name  # 普通字段   普通字段是属于对象的   每创建一个对象,就会在对象所存放的内存里创建一个对象的普通字段

    二、静态方法、普通方法、类方法

    静态方法
    静态方法直接通过类来调用
    当方法中不需要通过类中的值时,将方法写为静态方法

    普通方法
    由对象来调用,普通方法属于类

    类方法
    class Foo:
        def __init__(self, name):
            self.name = name
    
        def show(self):
            print(self.name)
    
        @staticmethod
        def static():
            print("static method")
    
        @classmethod
        def clsmethod(cls):
            # cls  为类名  那么可以通过cls后面加括号cls()来调用类
            print(cls)
    
    
    Foo.clsmethod()
    
    
    # 类只的所有方法:
    #    普通方法:至少一个self,通过对象来执行
    #    静态方法:可以有任意个参数,通过类来执行(也可通过对象那个来执行,但不到万不得已不要这么做)
    #    类方法:  至少一个cls,通过类来执行(也可通过对象那个来执行,但不到万不得已不要这么做)

    三、属性

    具有方法的代码写作方式,具有字段的访问形式
    @property @类名.setter @类名.deleter
    class pager:
        def __init__(self, all_count):
            self.all_count = all_count
    
        @property
        def all_pager(self):  # 调用时可以像普通字段一样取值  格式:对象名.字段名
            a1, a2 = divmod(self.all_count, 10)
            if a2 == 0:
                return a1
            else:
                return a1 + a2
    
        @all_pager.setter  # 调用时可以像普通字段一样赋值    格式:对象名.字段名 = xxx
        def all_pager(self, value):
            pass
    
        @all_pager.deleter
        def all_pager(self):  # 调用时可以像普通字段一样删除值    格式:del 对象名.字段名
            pass
    
    #调用
    pp = pager
    pp_get = pp.all_pager
    pp.all_pager = 'xxx'
    del pp.all_pager
    
    
    
    class class_attr:
    
    #属性的另外一种形式
        def f1(self):
            return 'test'
    
        def f2(self, value):
            pass
    
        def f3(self):
            pass
    
        foo = property(fget=f1, fset=f2, fdel=f3)
    
    
    #调用:
    p = class_attr()
    res = p.foo
    p.foo = 'xxx'
    del p.foo

    四、多态

        多态即多种形态,在运行时确定其状态,在编译阶段无法确定其类型,这就是多态。Python中的多态和Java以及C++中的多态有点不同,Python中的变量是弱类型的,在定义时不用指明其类型,它会根据需要在运行时确定变量的类型(个人觉得这也是多态的一种体现),并且Python本身是一种解释性语言,不进行预编译,因此它就只在运行时确定其状态,故也有人说Python是一种多态语言。在Python中很多地方都可以体现多态的特性,比如 内置函数len(object),len函数不仅可以计算字符串的长度,还可以计算列表、元组等对象中的数据个数,这里在运行时通过参数类型确定其具体的计算过程,正是多态的一种体现。有些朋友提出Python不支持多态,我是完全不赞同的.

        Python以它这种独有的方式体现多态的根本原因我觉得有两点:1)Python是解释性语言;2)Python中变量是弱类型的。所以Python体现多态的方式和Java决然不同,但是不能因为同Java中体现多态的方式不同就认为Python不支持多态,这种想法过于片面。

    来自:    http://blog.csdn.net/chongtianfeiyu/article/details/21894005

    面向对象-多态

    五、特殊方法

    #!/usr/bin/env python
    # _*_ conding:utf-8_*_
    
    
    class Foo:
    
        #构造方法
        def __init__(self,name):
            self.name = name
    
        #析构方法    进行垃圾回收时在内存中删除对象时,如果类中定义了析构方法时,执行析构方法中的内容的再删除
        def __del__(self):
            pass
    
        #call方法    实例名()    实例名后面加括号调用该实例的call方法
        def __call__(self, *args, **kwargs):
            pass
    
        #str方法   print(实例)时,未定义str方法时输出该实例的类名及在内存的中地址  定义后输出str方法里定义的内容
        def __str__(self):
            pass
    
        #dict方法   获取对象中封装的数据
    print(Foo.__dict__)
    
    #输出    {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__str__': <function Foo.__str__ at 0x0000000001116048>,
    # '__del__': <function Foo.__del__ at 0x000000000110BEA0>, '__call__': <function Foo.__call__ at 0x000000000110BF28>,
    # '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__init__': <function Foo.__init__ at 0x000000000110BE18>}
    obj = Foo('test')
    print(obj.__dict__)
    #输出  {'name': 'test'}
    
    
    class foo:
    
        def __init__(self,name):
            self.name = name
    
        def __getitem__(self, item):
            print("getitem")
    
        def __setitem__(self, key, value):
            print("setitem")
    
    
        def __delitem__(self, key):
            print("del item")
    
    obj = foo('xuanouba')
    obj['xuanouba']
    #结果  getitem
    obj['test'] = 'aa'
    print(obj.__dict__)
    #结果  setitem
    del obj['test']
    #结果 del item
    
    
    
    #__iter__方法   当将对象放到一个for循环里时,自动执行对象的__iter__方法
    class FOO:
    
        def __iter__(self):
            yield 1
            yield 2
    
    obj = FOO()
    for i in obj:
        print(i)

    六、其他方法

    super方法
    #super方法
    
    class Foo:
    
        def f1(self):
            print('Foo')
    
    class Bar(Foo):
    
        def f1(self):
            #主动执行父类的f1方法
            super(Bar,self).f1()
            print('Bar')
    
    obj = Bar()
    obj.f1()

    isinstance()方法
    # isinstance()
    #eg:
    isinstance(obj,Foo)
    res = isinstance(obj,Bar)    #判断obj实例是不是Bar类型
    print(res)
    res = isinstance(obj,Foo)    #(Foo是Bar的父类)判断是不是Bar类型的父类的类型
    print(res)
    issubclass()方法
    # issubclass()
    #eg:
    issubclass(Foo,Bar)    判断Foo类型是不是Bar类型的子类
    七、成员修饰符
    #!/usr/bin/env python
    # _*_ conding:utf-8_*_
    
    
    #成员修饰符:
    #    私有:只有类自己内部能访问,外部不能直接访问,在成员前加__(两个下划线),##也不能继承##
    #在外部也可访问私有字段或私有方法,类似obj._Foo__cc  #对象名._类名私有静态字段名 !! 不到万不得已不要用!!
    
    class Foo:
    
        __cc = 'name'
    
        def __init__(self,name):
            self.__name = name
    
        def f1(self):
            """
            访问私有成员时,只能同过这样的方式,在内部调用,然后外部通过共有方法的方式来间接访问,私有静态字段也一样
            :return:
            """
            print(self.__name)
    
        def f2(self):
            print(Foo.__cc)
    
    
    p = Foo('test')
    # print(p.__name)   #这样直接访问类的私有成员会报错
    # print(Foo.__cc)    #这样直接访问类的私有静态字段也会报错
    
    
    
    class FOO:
    
        def __init__(self,name):
            self.name = name
    
        def __f1(self):
            print("私有f1")
    
        def f1(self):
            print("共有f1")
    
    
    obj = FOO('ALEX')
    # obj.__f1()    #会报错,因为是私有方法
    obj.f1()
     
    八、实现有序字典
    #!/usr/bin/env python
    # _*_ conding:utf-8_*_
    
    #字典虽是无序的,但Python中的列表是有序的,利用这个特性,来实现的自定义的有序字典
    
    class Mydict(dict):     #继承Python提供的dict类
    
        def __init__(self):
            self.li = []        #创建一个空列表
            super(Mydict,self).__init__()   #执行dict类中的__init__方法
    
        def __setitem__(self, key, value):
            self.li.append(key)     #往字典中添加新的键值对时将key 追加到列表中
            super(Mydict,self).__setitem__(key,value)
    
        def __str__(self):
            temp_list = []   #设置一个临时空列表
            for key in self.li:
                value = self.get(key)
                temp_list.append("'{}':{}".format(key,value)) #将每一对键值对以 "'a':1" 这样的方式作为一个字符串追加到临时列表中
            temp_str = '{' + ",".join(temp_list) + '}'    #最后已列表的形式返回给用户
            return temp_str
    
    obj = Mydict()
    obj['a'] = 1
    obj['b'] = 2
    print(obj)
    九、单例模式
    class Foo:
    
        instance = None
    
        def __init__(self,name):
            self.name = name
    
        @classmethod
        def get_instance(cls):      #类方法,通过类直接调用,
            if cls.instance:             #如果现在已经有实例,则将实例直接返回给对象
                return cls.instance
            else:                      #如果现在没有实例,那么创建一个实例,然后返回给对象
                obj = cls('test')
                cls.instance = obj
                return obj
        #    这样的话每次实例化一个对象的时候,都返回的是同一个实例
    
    obj1 = Foo.get_instance()
    obj2 = Foo.get_instance()
    print(obj1)
    print(obj2)

    更多关于单例模式:

        http://www.cnblogs.com/seesea125/archive/2012/04/05/2433463.html

     单例模式介绍 单例模式

  • 相关阅读:
    寿司点餐系统Sprint1总结
    寿司点餐系统一周总结
    对点餐APP现阶段开发的问题
    寿司点餐系统11.16
    Sprint
    R扩展包
    实验8 SQLite数据库操作
    实验7 BindService模拟通信
    实验6 在应用程序中播放音频和视频
    实验5 数独游戏界面设计
  • 原文地址:https://www.cnblogs.com/xuanouba/p/5624023.html
Copyright © 2011-2022 走看看