Chapter13 类

接口是如何体现的?

多态

# coding:utf-8

class P(object):
    def foo(self):
        print 'I am p foo'

class C(P):
    def foo(self):
        P.foo(self)
        print 'I am c foo'

c = C()

c.foo()

看看 c=C() 按照Java应该是 P c = new C() ,但是因为python不需要写类型。所以 c = C() 这就是多态的表示了.

这里要注意一点,当覆盖__init__的时候不要忘记调用父类的__init__.

动态添加属性

这个有点夸张呀。

关于private,public,protected

Python中是没有这些关键字的。通过 Attr 这种方式来混淆Attr属性,实际上是被混淆成了额 ```ClassName_Attr```,所以这种混淆本质上意义不大,但是可以有效的区分,父类和子类的同一个属性。

另外在模块中的单下划线的好处是,当模块被加载的时候 属性不会被执行。

描述符

描述符是针对属性的,是属性的一个代理。"get"获取,"set"修改,"delete"删除.就是实现类中的 __get__, __set__ 和 __delete__。 而我们真正需要的是类似java的getter和setter,那么这是通过 property来实现的。避免使用描述符。

# coding:utf-8

class DevNull2(object):
    def __get__(self, instance, owner):
        print 'Accessing attribe ... ignoring'

    def __set__(self, instance, value):
        print 'attmpt to assing %r ... ignoring' % (value)

class C2(object):
    foo = DevNull2()

    def __init__(self, x):
        assert isinstance(x, int), \
        '''"x" must bie an integer'''

        self.__x = ~x

    def get_x(self):
        print 'get_x is called'
        return ~self.__x

    def set_x(self, val):
        print 'set_x is called'
        self.__x = ~val

    x = property(get_x, set_x)


c2 = C2(5)

# 下面是对foo进行赋值,那么就会默认执行 __set__
c2.foo = 'bar'

# 下面是获取foo,也就是会调用 __get__
x = c2.foo

# 这里的描述符和Java是有些区别的,与getter和setter
# Java中是写在C的类中,对foo进行封装,而这里是对foo所属的类进行封装

# 类似于java中的封装是 propterty这个函数的处理
a = c2.x
c2.x = 9

输出:
attmpt to assing 'bar' ... ignoring
Accessing attribe ... ignoring
get_x is called
set_x is called

使用下面的技巧更加容易实现getter和setter

# 先前的propterty 使得getX和setX能够被外部调用,下面的技巧将避免这个问题

class HideX(object):
    def __init__(self, x):
        self.__x = ~x

    @property
    def x(self):
        return ~self.__x

    @x.setter
    def x(self, val):
        self.__x = ~val


h = HideX(2)

print h.x

关于抽象类和接口

参考: 抽象类和接口

results matching ""

    No results matching ""