我在 StackOverflow 上看到过一些关于这个主题的讨论,但我没有看到任何有助于我理解以下几点的内容:
我来自 C++ 背景,最近我开始学习 Java。
在 C++ 中,当使用 protected 时,只有子类可以访问该成员(类似于 Java 中的 Field)。
在 C++ 中,还有“ friend ”类可以访问提供“友谊”的类的私有(private)/ protected 成员。
这有点类似于 Java 中的“包”字段修饰符(默认字段修饰符),除了在 C++ 中友谊允许访问所有私有(private)成员,但在 Java 中,来自同一包中的类的访问是特定于类字段的。
我无法理解的是,假设我只想向子类授予访问权限,这是我可以在 C++ 中通过在不“提供”友谊的类中声明 protected 成员来实现的。
但是在 Java 中,我不知道我该怎么做,因为通过使用“protected”字段修饰符——我还可以访问包中的所有类。
我发现这样做的唯一方法是声明该字段 protected 并将该类隔离在其包中。
从这里,我得出的结论是,一个包中的类的分组必须基于类之间的“友谊”来完成。
这确实是包分组的主要考虑因素吗?
还有一点我不明白,
在 Java 中,假设我在类 A 中有两个字段:b、c。
我想让 B 访问 b 而不是 c,
我想让 C 访问 c 但不访问 b。
对于“世界”,我希望 b,c 隐藏起来。
如何做呢?
我想 B,C 应该都和 A 在同一个包里。
但是通过使用 package 修饰符声明 b,c,我让 B,C 访问 b 和 c。
Java 有办法做到这一点吗?
希望对这个主题有一些解释
In C++ when protected is used only a subclass can access the member
(the analog to Field in Java).
访问说明符也适用于成员函数/方法,而不仅仅是成员变量/字段。
In C++ there is also the "friend" classes that can have access to
private/protected mambers of the class that giving "friendship". This
is little bit analogous to "package" field modifier in Java (default
field modifier), except that in C++ a friendship gives access to all
private members, but in Java the access from classes in the same
package is specific for a class field.
不仅有friend
类还有函数。
Java 的 package-private access 确实很相似,但不是完全替代。更好的表达方式是,这两个功能具有它们解决的问题的子集。有些问题可以通过 friend
解决,但不能通过 package-private 解决,反之亦然。
What I couldn't understand is, assuming that I want to give access
only to subclasses, this is something I can do in C++ by declaring the
members protected in a class that doesn't "give" friendships.
But in Java, I don't know how can I do it,
答案是:你不能。
since by using "protected" field modifier - I also give access to
all classes in the package.
没错。
The only way that I find to do it is to declare the field protected and
have the class isolated in its package.
从技术上讲,是的。但这会产生其他问题。您的类(class)将无法再访问其先前包的包私有(private)元素。假设您的 BaseClass
曾经在 com.example.one
中。您将其移动到 com.example.two
。现在它将无法再访问 com.example.one
的其他包私有(private)类。
Is this indeed the leading consideration in package grouping?
没错,Java就是这么设计的。您可以尝试与语言规则作斗争,但这对任何编程语言来说都是一场必败之战。
Another thing I don't understand, In Java, assuming I have two fields
in the class A: b,c. I want to give B access to b but not to c, and I
want to give C access to c but not to b. and to the "World" I want b,c
to be hiden. How can it be done?
它不能以干净的方式完成(干净的意思是:没有任何需要您在运行时检查调用堆栈并抛出异常的 hack)。
如果您因为设计公共(public) API 而担心这种情况,通常可以完美运行的低技术解决方案是创建一个或多个 *.internal
包并清楚地记录以下事实:这些不应在客户端代码中使用。