为什么我能在非公开课上有公共会员?

时间:2014-03-03 00:27:43

标签: java class public-members

class MyClass 
{
    public static final int num=90;
}
  • 为什么我可以在非公开课上创建公共会员?
  • 是否有另一种访问此会员的方式我不知道(除了通过班级名称)?

4 个答案:

答案 0 :(得分:16)

由于你的问题是关于members,我将讨论字段和方法(非静态; Anthony Accioly's answer触及另一个好的用例,其中还包括静态字段。)

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

扩展Mik378's回答,请考虑以下(设想示例):

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方法或它们扩展的类。

实例:

  • 您使用此时间覆盖匿名内部类中的公共方法(例如,每次在匿名public void actionPerformed中覆盖ActionListener时)。< / p>

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

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

  • 更复杂的例子是在java.sql.DriverManager中使用java.sql.Driver(一般来说,工厂类设计大量使用这个概念) - SQL驱动程序实现可能无法实现类public(例如Oracle驱动程序生成非公共Connection个对象)。

  • 还有更多...如果你留意这个例子,你会惊奇地发现它真的很普通!

答案 1 :(得分:4)

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

package package1;

class MyDefaultClass {

    public static final int MY_CONSTANT = 0xCAFEBABE;
}

public class PublicExporter extends MyDefaultClass {

}

现在public类充当桥梁,您可以使用其他软件包中的MyDefaultClass public个成员。

package package2;

import package1.PublicExporter;

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

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

import static package1.PublicExporter.MY_CONSTANT;

public class Consumer {
    public static void main(String[] args) {
        System.out.printf("%x\n", MY_CONSTANT);
    }
}

答案 2 :(得分:3)

当属于封闭类public的{​​{1}}方法返回其内部类A的引用(public超类型引用,如接口)时默认范围,外部客户端(B之外的包)只能调用A的方法,但不能创建自己的新{{1}个实例}}

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

这种建模在某些环境中非常有用,可以改进代码设计。

答案 3 :(得分:0)

当你声明一个变量public时,它基本上变成了那个;它可以在整个程序中看到,没有任何特殊的getter / setter。该课程不一定需要public才能使其成员公开。

请记住,在Java中,每个编译单元(。java文件)只能有1个公共类,并且该公共类需要与编译单元具有相同的名称。除此之外,它不“拥有”关键字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的情况下访问它们。但是,公共类不是唯一可以拥有公共变量的类。