为什么我可以在非公开的课堂上有一个公开的成员


class MyClass 
{
public static final int num=90;
}
  • 为什么允许我在非公共类中创建公共成员
  • 有没有其他我不知道的访问该成员的方法(除了通过类名)

由于您的问题是关于成员,我将同时讨论字段和方法(非静态;Anthony Accioly的回答涉及另一个很好的用例,其中也包括静态字段)。

虽然在许多情况下,这只是语言语法的模糊结果(特别是:非公共类中的公共字段,如您的示例片段中所示),但有充分的理由需要能够在非公共类使用公共方法

扩展Mik378的答案,例如,考虑以下(人为的例子):

import ...;
class BleebleAscendingComparator implements Comparator<Bleeble> {
@Override public int compare (Bleeble o1, Bleeble o2) { ... }
}
class BleebleDescendingComparator implements Comparator<Bleeble> {
@Override public int compare (Bleeble o1, Bleeble o2) { ... }
}
public class BleebleView {  
public enum SortMode { ASC, DESC };
public Comparator<Bleeble> getDisplayOrderComparator (SortMode mode) {
if (mode == SortMode.ASC)
return new BleebleAscendingComparator();
else
return new BleebleDescendingComparator();
}
}

您不能直接在该上下文之外实例化其中一个Comparator实现,但它们必须覆盖Comparator的公共方法,并且可以通过Comparator接口访问它们的功能。

同样的推理适用于例如privateprotected内部类。如果不能声明方法public,那么就无法覆盖它们继承的接口或扩展的类的public方法。

实际示例:

  • 每次覆盖匿名内部类中的公共方法时(例如,每次覆盖匿名ActionListener中的public void actionPerformed时),都会使用此

  • 考虑任何要存储在HashMap中的非公共类。您将覆盖该非公共类中的公共equals()hashCode(),并且HashMap的实现可以访问它们,而不管该类是非公共的。

  • 经常被重写的public toString()是潜在非公共类的公共成员的另一个常见示例。

  • 一个更复杂的例子是在java.sql.DriverManager中使用java.sql.Driver(通常,工厂类型的设计会大量使用这个概念)——sql驱动程序实现可能不会公开实现类(例如,Oracle驱动程序生成非公共的Connection对象)。

  • 更多。。。如果你留意这方面的例子,你会惊讶于它的普遍性!

不要忘记,具有default访问权限的类可以由同一包中的public类进行子类化。

package package1;
class MyDefaultClass {
public static final int MY_CONSTANT = 0xCAFEBABE;
}
public class PublicExporter extends MyDefaultClass {
}

现在public类充当了一个桥接器,您可以使用其他包中的MyDefaultClasspublic成员。

package package2;
import package1.PublicExporter;
public class Consumer {
public static void main(String[] args) {
System.out.printf("%xn", PublicExporter.MY_CONSTANT);
}
}

消费者甚至可以导入静态成员:

import static package1.PublicExporter.MY_CONSTANT;
public class Consumer {
public static void main(String[] args) {
System.out.printf("%xn", MY_CONSTANT);
}
}

当属于封闭类Apublic方法向其具有默认作用域的内部类B返回引用(public超类型引用,类似于接口)时,外部客户端(在A的包之外)只能调用B的方法,但不能创建自身的B的新实例。

如果B的方法不是public,则外部客户端无法访问它们,更糟糕的是:由于没有很好地实现其接口,将导致编译错误。

这种建模在特定的上下文中可能很有用,可以改进代码设计。

当您声明一个变量public时,它本质上就是这样;它可以在整个程序中看到,而无需任何特殊的getter/setter。该类不一定需要是public才能使其成员也是公共的。

请记住,在Java中,每个编译单元(.java文件)只能有一个公共类,并且该公共类需要与编译单元具有相同的名称。除此之外,它并不"拥有"关键字public的所有权。

您将num声明为publicstatic,这一事实允许您说出System.out.println(MyClass.num)。public属性允许您直接获取num变量。因此,您不必创建一个方法来为您返回num。因为它是公开的,你也可以说

MyClass mc = new MyClass();
System.out.println(mc.num);

但是,由于您还添加了static声明,因此应该仅通过类名访问它,即MyClass.num

要点:公共变量可以存在于任何类型的类中,它们允许您在不需要getter和setter的情况下访问它们。然而,公共类并不是唯一可以拥有公共变量的类。

相关内容

最新更新