外部文件中的嵌套/内部类

49

我有一个类MyClass和一个内部类MyNestedClass,就像这样:

public class MyClass {
  ...
  public class MyNestedClass {
    ...
  }
}

这两个类非常长。因此,我想将它们分成两个不同的文件,而不破坏层次结构。这是因为嵌套类不应该对使用 MyClass 的程序员可见。

有办法实现吗?


类似的问题:https://dev59.com/tXE85IYBdhLWcg3wdDSz - Terrance
我曾遇到类似的问题并在这里找到了解决方法:https://dev59.com/iF4d5IYBdhLWcg3wB-mI 至少这是我能想到的最好方案。 - John
6个回答

20

你可以将内部类变为包私有的,这意味着它只能被完全相同包中的其他类访问。在标准 JDK 包(如 java.langjava.util)中,隐藏类经常使用此方法。

在 pkg/MyClass.java 中实现:

public class MyClass {
  ...
}

在 pkg/MyHiddenClass.java 文件中

class MyHiddenClass {

  final MyClass outer;

  MyHiddenClass( MyClass outer )
  {
      this.outer = outer;
  }
  ...
}

现在,当你想要访问外部类的方法或变量时,你需要在它们前面加上outer. 但实际上,当编译器合成外部实例的引用时,你会得到与之前基本相同的功能。


12
尽管如此,从技术上讲,这仍不是一个内部类。 - AJMansfield
12
MyClass的私有属性无法从MyHiddenClass中访问,而MyHiddenClass是受保护的,而不是私有的。 - SparK

8

不可以将Java源代码分割成多个文件。你需要类似于C#中的部分类的结构,而Java没有这样的功能。


7

1
谢谢。这个评论让我意识到我应该重新做我的工作。 :) - Pasha
1
PS,实际上不是这样的。 :) 我只是发现我需要在我的类上承担这种责任。 - Pasha

5

内部类的对象会隐式地引用父类对象。 如果嵌套类不是static(它是内部类),则无法这样做。但是,如果嵌套类不需要直接访问父类实例并且不需要访问私有字段,则应该可以进行重构,将内部类移出并且不要声明为public(不能在该包之外访问)。


4

是的,可以使用级联跳转器(cascade-jumper)。级联跳转器是在其他地方定义的抽象和非静态内部类。

MyClass.java

public class MyClass {
  public abstract class CascadeJumper {}
}

我的嵌套类

private class MyNestedClass extends MyClass.CascadeJumper {
  MyNestedClass(MyClass dollarOne) {
    dollarOne.super(); // yes, is possible!
  }
}

敬礼


我不认为这会起作用。从MyNestedClass,你仍然只能访问MyClass的公共方法和字段,就像从任何其他类一样。 - Alphaaa
@Alphaaa 不,你可以从 MyNestedClass 访问 MyClass 中的私有字段、私有枚举、私有类和私有方法、私有构造函数,简而言之,所有东西都可以访问!试试看吧! - Grim
我做到了,而你却做不到。事实上,即使是普通的内部类也不能这样做,根据这个链接:http://docstore.mik.ua/orelly/java-ent/jnut/ch03_13.htm。Java编译器实际上通过生成包私有方法来转换对外部类私有字段的访问,并将任何直接字段访问替换为对这些生成方法之一的调用。所有类实际上都是顶级的。 - user2219808
尽管看起来很酷,但这并不起作用。私有属性意味着它们只能从类内部访问。当我的嵌套类是外部类时,它不起作用。只有在将外部类的必要属性引用为抽象嵌套超类的受保护属性时,才可能起作用。 - Quan To

1

你可以创建抽象基类,然后在两个类中进行扩展。

但是,如果这些类很大,最好重新评估你的类设计,并查看是否可以重构为每个表示一个关注点的类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接