为什么 Java 与 Python 在对待成员变量的访问控制方式截然相反?

转自知乎:http://www.zhihu.com/question/20885435

为什么 Java 与 Python 在对待成员变量的访问控制方式截然相反?

Java提倡成员变量应该是private的对外不可见的,然后提供get/set方法进行操作,而Python恰好相反,python 鼓励成员变量应该尽可能是公开的,然后直接使用成员变量。 感觉Python这样做有点违背“封装”的特性,还有他们在面向对象的概念上差别也十分的大,说一下你的理解。


谢谢 @秦双彪 邀请。
接口设计,必然有对外和对内的区分,使用 Python 也不例外。只不过 Python 的风格是信任开发者,让开发者自我约束,而不用编译期检查之类的强制措施。一般在 Python 中对于类的私有成员,用一个下划线开头即表示私有,外部调用者原则上不应该去依赖这些接口,但某些特殊的场合(比如库本身的测试用例)是可以去破坏这个规则的,这也是 Python 社区反教条主义的一个体现。甚至有的时候,这种约束都不用在变量名上体现,仅仅在文档上体现就已经足够——有文档的就是 API,没有公开文档描述的就是私有接口。
至于 Java 选择编译期检查的强制约束,我也只能说这是 Java 的风格,对比 Python 的做法并无优劣之分。事实上在 Java 中 private 的约束也一样并非不可突破,使用反射就可以绕过这一限制,不少 ORM 工具就使用反射向 private 的属性注入值。

再说到用 getter 还是直接赋值的问题,在 C/C++ 中避免向结构体属性直接赋值有非常充足的理由——那样会导致额外的内存布局依赖,所以对于需要暴露的 API,我们只能选择书写 getter 函数和 setter 函数;而对于 Python 而言,直接存取属性并没有面向特定的内存布局,反而和调用方法一样,是需要经过特定内部方法访问的,即:

# 三者等效
print spam.egg
print getattr(spam, "egg")
print object.__getattribute__(spam, "egg")
所以再自己去书写一个一个什么都不做,只是转发一下的 getter 或 setter 就是画蛇添足了。更何况,在 Python 的对象模型中,对象 只有属性,没有方法 ——方法是一种被称之为 descriptor 的特殊属性。
而 Java 使用 getter/setter 也是一种约定,约定一个对象对外公开的 只有方法,没有属性 ,只是 Java 的实现非常恶心,即使是简单的赋值、取值的 getter/setter 也需要自己一个个书写。Ruby 采取的是和 Java 一样的概念,但 Ruby 可以用 attr_accessor 这样的语法糖。另一个运行于 JVM 的语言 Scala 则采取和 Ruby 类似的做法弥补了 Java 的教条带来的麻烦,在字节码中自动生成 getter/setter 方法。

总结:除了 getter/setter 需要全部手动书写的问题 Java 略有槽点之外,其他的纯粹是风格差异。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值