gpt4 book ai didi

java - 是否可以使用在其父类(这是内部类)中实现的类?

转载 作者:行者123 更新时间:2023-12-02 05:35:03 25 4
gpt4 key购买 nike

让我们考虑一个简单的类 Action,它旨在遍历多个阶段(预定义的状态顺序),直到到达最后一个阶段。这些阶段应由公共(public)类 Stage 的子类表示,并封装 Action 类在方法 proceed() 执行时执行的代码。叫。此方法还返回下一个阶段。

我希望这是一个合理的设计,因为我认为它比具有状态常量的枚举和具有 switch-case 的 proceed() 更干净。

可以简单地使用内部类来实现:

public class Action {

private int m;
private Stage stage;

public Action() {
stage = new FirstStage();
}

public void proceed() {
if (stage != null) {
stage = stage.proceed();
}
}

public interface Stage {

/**
* Executes current stage and returns next stage.
*
* @return
*/
Stage proceed();
}

public class FirstStage implements Stage {

@Override
public Stage proceed() {
m = 100;
return new SecondStage();
}

}

public class SecondStage implements Stage {

@Override
public Stage proceed() {
//do something
return null; // last stage
}

}
}

但是我对松散地驻留在 Action 类中的所有 Stage 子类感到恼火,尽管它们属于在一起。为了解决这个问题并获得方便的命名空间,将阶段类实现为 Stage 的内部类会很有用。因此,我们会编写 Stage.First 而不是 FirstStage,我认为这样更清晰。

public class ActionB {

private int m;
private Stage stage;

public ActionB() {
stage = new Stage.First(); // error
}

public void proceed() {
if (stage != null) {
stage = stage.proceed();
}
}

public abstract class Stage {

/**
* Executes current stage and returns next stage.
*
* @return
*/
public abstract Stage proceed();

public class First extends Stage {

@Override
public Stage proceed() {
m = 100;
return new Second();
}

}

public class Second extends Stage {

@Override
public Stage proceed() {
//do something
return null; // last stage
}

}
}
}

我必须更改的第一件事是使 Stage 成为一个抽象类,因为接口(interface)是静态的,因此无法访问 Action 的成员。

现在的问题是在构造函数中实例化第一阶段。编译器错误:

error: an enclosing instance that contains ActionB.Stage.First is required

当然,我明白内部类需要其外部类的实例。但是如果外部类是抽象的甚至是静态的(接口(interface))怎么办?这不应该起作用吗?

还有办法实现嵌套吗?还是这个设计很糟糕?

最佳答案

您不需要将 switch 语句与 enum 一起使用。您也可以对它们使用干净的继承概念:

public class Action {
private int m;
private Stage stage;

public Action() {
stage = Stage.FIRST;
}
public void proceed() {
if (stage != null) {
stage = stage.proceed(this);
}
}

enum Stage {
FIRST {
@Override
Stage proceed(Action a) {
a.m = 100;
return SECOND;
}
},
SECOND {
@Override
Stage proceed(Action a) {
//do something
return null; // last stage
}
}
;
/**
* Executes current stage and returns next stage.
*/
abstract Stage proceed(Action a);
}
}
<小时/>

尝试嵌套类的问题是无法解决的:将 abstractStage 的所有子类声明为非static 时内部类,这些类在构造时需要 Stage 的外部实例。但是,没有实例可用作外部实例,因为 Stageabstract 并且所有子类都是需要现有实例的内部类,从而创建了一个鸡和-鸡蛋问题。

正如您已经发现的,您无法声明内部类static,因为Stage是非static并且Java不允许 >staticstatic内部类中的成员,但无论如何它都没有帮助,就好像内部类是static它们没有外部Action 实例也是您尝试的全部内容。否则,您可以简单地使用我上面的解决方案,该解决方案已经通过引入参数来处理内部枚举始终是静态的事实。

因此,预期的类似 namespace 的嵌套仅适用于 static 内部类,这不太适合使用隐式外部实例的想法:

public class ActionB {

private int m;
private Stage stage;

public ActionB() {
stage = new Implementations.First(this);
}
public void proceed() {
if (stage != null) {
stage = stage.proceed();
}
}

public abstract class Stage {
public abstract Stage proceed();
ActionB outer() { return ActionB.this; }
}
static class Implementations {

public static class First extends Stage {
First(ActionB outer) { outer.super(); }

@Override
public Stage proceed() {
outer().m = 100;
return new Second(outer());
}
}

public static class Second extends Stage {
Second(ActionB outer) { outer.super(); }

@Override
public Stage proceed() {
//do something
return null; // last stage
}
}
}
}

如果您走到这一步,最好将我建议的第一个解决方案与提供所需无参数方法的前端类一起使用:

public class Action {

private int m;
private Stage stage;

public Action() {
stage = new Stage(StageImpl.FIRST);
}
public void proceed() {
if (stage != null) {
stage = stage.proceed();
}
}

public class Stage {
final StageImpl stage;
Stage(StageImpl next) {
stage=next;
}
public Stage proceed() {
StageImpl next=stage.proceed(Action.this);
return next==null? null: new Stage(next);
}
}
enum StageImpl {
FIRST {
@Override
StageImpl proceed(Action a) {
a.m = 100;
return SECOND;
}
},
SECOND {
@Override
StageImpl proceed(Action a) {
//do something
return null; // last stage
}
}
;
abstract StageImpl proceed(Action a);
}
}

因此,您已将实现限制在某种 namespace (StageImpl) 中,并拥有一个前端类 Stage,它提供了预期的 proceed() 语义不变的方法。

关于java - 是否可以使用在其父类(这是内部类)中实现的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25065419/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com