什么时候使用嵌套Java类才是真正有用的?

什么时候使用嵌套Java类才是真正有用的?,java,class,nested,Java,Class,Nested,你能给我一个嵌套java类有用的具体例子吗? 我正在研究它,我理解它是如何工作的,但我无法想象一个真正需要使用它的真实情况 多谢各位 Marco它还用于实现 首先,您需要创建一个静态嵌套类,然后将所有参数从外部类复制到构建器类 它还用于实现 首先,您需要创建一个静态嵌套类,然后将所有参数从外部类复制到构建器类 我发现当我有一个类是另一个类的一部分时,它们很有用。 例如,如果我有基本抽象类: abstract class Unit { private int HP; .... abst

你能给我一个嵌套java类有用的具体例子吗? 我正在研究它,我理解它是如何工作的,但我无法想象一个真正需要使用它的真实情况

多谢各位


Marco

它还用于实现

首先,您需要创建一个静态嵌套类,然后将所有参数从外部类复制到构建器类


它还用于实现

首先,您需要创建一个静态嵌套类,然后将所有参数从外部类复制到构建器类


我发现当我有一个类是另一个类的一部分时,它们很有用。 例如,如果我有基本抽象类:

abstract class Unit {
  private int HP;
  ....
  abstract class AI {
    abstract void heal();
  }
}
稍后,我可以指定我正在设计的单元类型:

class Infantry extends Unit {
  ...
  class InfantryAI extends AI {
    void heal() { this->HP++; }
  }
}
你看到的是第二个——非静态嵌套类,也就是像AI和步兵AI这样的内部类,可以作为自己的属性访问周围类的单位和步兵私有属性,这种访问权限沿着继承树向下传播


至于它们是必要的-这些OOP构造都不是真正必要的,但是如果在设计阶段对您有意义的话,就像我认为的那样,AI是每种单元类型的一部分,这样它就可以控制它的私有成员,这可能是合乎逻辑的,然后你就可以使用它们了。

我发现它们很有用,因为我的类是彼此共同进化的一部分。 例如,如果我有基本抽象类:

abstract class Unit {
  private int HP;
  ....
  abstract class AI {
    abstract void heal();
  }
}
稍后,我可以指定我正在设计的单元类型:

class Infantry extends Unit {
  ...
  class InfantryAI extends AI {
    void heal() { this->HP++; }
  }
}
你看到的是第二个——非静态嵌套类,也就是像AI和步兵AI这样的内部类,可以作为自己的属性访问周围类的单位和步兵私有属性,这种访问权限沿着继承树向下传播


至于它们是必要的-这些OOP构造都不是真正必要的,但是如果在设计阶段对您有意义,就像我认为的那样,AI是每个单元类型的一部分,这样它就可以控制它的私有成员,那么您可以使用它们。

嵌套类是组织代码的一种方式,可以说,有点紧的封装。虽然嵌套类并不适用于所有情况,但它们在处理事件时特别有用

嵌套类的范围由其封闭类的范围限定。因此,如果类B是在类A中定义的,那么B并不独立于A而存在。嵌套类具有访问权限。到嵌套它的类的成员,包括私有成员。但是,封闭类无权访问嵌套类的成员。直接在其封闭类范围内声明的嵌套类是其封闭类的成员

最常用的是内部类。内部类是非静态嵌套类。它可以访问它的外部类的所有变量和方法,并且可以像外部类的其他非静态成员那样直接引用它们


最后还有匿名内部类,它们是没有名称的内部类。

嵌套类是组织代码的一种方法,可以说,是一种紧密封装。虽然嵌套类并不适用于所有情况,但它们在处理事件时特别有用

嵌套类的范围由其封闭类的范围限定。因此,如果类B是在类A中定义的,那么B并不独立于A而存在。嵌套类具有访问权限。到嵌套它的类的成员,包括私有成员。但是,封闭类无权访问嵌套类的成员。直接在其封闭类范围内声明的嵌套类是其封闭类的成员

最常用的是内部类。内部类是非静态嵌套类。它可以访问它的外部类的所有变量和方法,并且可以像外部类的其他非静态成员那样直接引用它们


最后还有匿名内部类,它们是没有名称的内部类。

关于何时使用嵌套类的最简明的总结是:当该类在逻辑上是外部类API的一部分时,或者当它封装特定于外部类的行为时

例如,Map.Entry:它是映射中的一个条目。它在逻辑上是Map的API的一部分,所以将它放在Map中是有意义的

另一个常见的例子是:您使用构建器来创建一个对象,因此将其放入该对象中是有意义的

这些类只能在使用外部类的上下文中使用:有时您可能会将Map.Entry本身作为某种pair类使用;有时候你可能想单独使用一个构建器,例如,作为一个方法的参数,这个方法把东西放到构建器中,但实际上并不做构建本身。这些案例 它们可能很少远离也使用外部类的代码:您仍然在使用外部类的API的某些方面,因此它们在逻辑上仍然属于该API

你可以把这些类放在顶层,与主类一起。您可能不想这样做的原因如下:

它使名称空间变得混乱。如果您有Foo、Bar、Baz等类,那么将FooBuilder、BarBuilder、BazBuilder放在顶级只会使您更难看到有用的顶级类。 为每种消息类型生成一个生成器类。考虑到谷歌代码中使用的协议缓冲区的数量,这种混乱将过于麻烦。 嵌套类可以访问外部类的私有字段,这可以帮助您在不必要地公开这些字段的情况下执行某些操作。 您可以通过限定外部名称来引用嵌套类,例如outer.Builder,而不必显式导入some.pkg.OuterBuilder和some.pkg.outer。诚然,我并不真正关心导入的数量,因为我只是在intellij中保存它们。
您还可以使用它们来封装类中的内部逻辑或中间状态:例如,当我发现自己在类中的私有方法之间传递相同的N个参数时,我喜欢定义私有嵌套类。这是你不希望班外的人关心的事情;它只是在类内部方便而已。

关于何时使用嵌套类的最简明的总结是:当该类在逻辑上是外部类API的一部分时,或者当它封装特定于外部类的行为时

例如,Map.Entry:它是映射中的一个条目。它在逻辑上是Map的API的一部分,所以将它放在Map中是有意义的

另一个常见的例子是:您使用构建器来创建一个对象,因此将其放入该对象中是有意义的

这些类只能在使用外部类的上下文中使用:有时您可能会将Map.Entry本身作为某种pair类使用;有时候你可能想单独使用一个构建器,例如,作为一个方法的参数,这个方法把东西放到构建器中,但实际上并不做构建本身。这些情况可能很少远离也使用外部类的代码:您仍然在使用外部类的API的某些方面,因此它们在逻辑上仍然属于该API

你可以把这些类放在顶层,与主类一起。您可能不想这样做的原因如下:

它使名称空间变得混乱。如果您有Foo、Bar、Baz等类,那么将FooBuilder、BarBuilder、BazBuilder放在顶级只会使您更难看到有用的顶级类。 为每种消息类型生成一个生成器类。考虑到谷歌代码中使用的协议缓冲区的数量,这种混乱将过于麻烦。 嵌套类可以访问外部类的私有字段,这可以帮助您在不必要地公开这些字段的情况下执行某些操作。 您可以通过限定外部名称来引用嵌套类,例如outer.Builder,而不必显式导入some.pkg.OuterBuilder和some.pkg.outer。诚然,我并不真正关心导入的数量,因为我只是在intellij中保存它们。
您还可以使用它们来封装类中的内部逻辑或中间状态:例如,当我发现自己在类中的私有方法之间传递相同的N个参数时,我喜欢定义私有嵌套类。这是你不希望班外的人关心的事情;这只是在课堂上很方便。

当你需要的时候。如果一个测试需要一个类的模拟/特殊实现,那么你可以将它嵌套在测试类中,因为它没有在其他任何地方使用。Hey Marco,这确实是一个有趣的问题,尽管它可能是基于观点的,所以没有明确的正确答案。一个很好的例子是,当您想要定义一个包装类专用的容器类时。我经常使用的模式是类中的嵌套枚举。例如,这允许您拥有一个名为Process的类和一个名为Status的嵌套枚举。在process类中,您只需将枚举引用为Status。在Process类之外,您将其称为Process.Status,这是一种非常描述性的方法。在很多情况下,嵌套类都是合适的。这主要是一种结构选择。。。特定接口的内部实现、内部状态保持类,甚至lambda都相当于内部类。请注意,非静态类可以看到定义类的私有成员。如果一个测试需要一个类的模拟/特殊实现,那么你可以将它嵌套在测试类中,因为它没有在其他任何地方使用。Hey Marco,这确实是一个有趣的问题,尽管它可能是基于观点的,所以存在
没有明确正确的答案。一个很好的例子是,当您想要定义一个包装类专用的容器类时。我经常使用的模式是类中的嵌套枚举。例如,这允许您拥有一个名为Process的类和一个名为Status的嵌套枚举。在process类中,您只需将枚举引用为Status。在Process类之外,您将其称为Process.Status,这是一种非常描述性的方法。在很多情况下,嵌套类都是合适的。这主要是一种结构选择。。。特定接口的内部实现、内部状态保持类,甚至lambda都相当于内部类。请注意,非静态类会看到定义类的私有成员。非常感谢:您友好地回答了问题,您在这里提供的信息正是我想要的,我自己找不到。祝你有美好的一天!非常感谢:您友好的回答,您提供的信息正是我想要的,我自己找不到。祝你有美好的一天!感谢