class and private variables
1 2 3 4 5 6 7 8 9 10 11 12 | class Test1: def __init__( self ): self.__test = 1 def getvalue( self ): return self.__test class Test2( Test1 ): def __init__( self ): Test1.__init__( self ) self.__test = 2 test = Test2() |
为什么print test.getvalue()返回1?
在python中,
如果您希望子类看到变量,而仍然希望它不属于公共接口的一部分,请使用单个下划线
这种行为是由于用EDCOX1 OR 9来开始的属性名称的命名。基本上,
它在其他语言中也有同样的作用,比如Java(试试它!)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Test1 { private int test = 1; public int getValue() { return test; } } class Test2 extends Test1 { private int test = 2; } public class Test { // Run the test public static void main(String[] args) { Test2 t = new Test2(); System.out.println(t.getValue()); } } |
(为什么我要在Python相关的问题中发布Java代码?)因为一些评论说"这在任何OO语言中都不起作用"和"这就是为什么你不为私有变量使用名字过滤"——Java与Python相比采取了另一种面向对象的方法,并且不为私有变量使用名字过滤,但行为是相同的。
test1中声明的方法可以访问test1的私有变量。除非子类重写该方法,否则从子类调用该方法不会更改任何内容。不是私有成员在子类中"消失"或"被覆盖"。它们仍然存在,并且可以通过父类的方法访问。
只有当test2为getValue()声明自己的实现时,test1的私有成员才变得不可访问,test2的私有成员才变得可访问。
换句话说,可以说私有成员不是"虚拟的"(或"可重写的")。它们是类及其方法的实现细节,不应该被重写。
如果您希望传统的OO行为,其中子类成员重写其父级,则使用Python、Java或C++中的一种虚拟方法,即C *、Delphi;而不是私有属性。如果要实现没有名称冲突的内容,请使用私有属性。