gpt4 book ai didi

java - 如何与任何类共享自返回方法链?

转载 作者:搜寻专家 更新时间:2023-10-31 20:34:36 24 4
gpt4 key购买 nike

更新:我明白了!事实证明,蜘蛛鲍里斯的“GENERICS”评论正是我需要的线索。

首先是原始问题和损坏的代码,然后是解决方案。我的通用设计在下面是 needer-needable。

原始问题和非工作代码

在过去的几年里,我断断续续地尝试使自返回方法链与其他类“共享”。这是为了避免必须在每个子类中复制每个自返回函数的巨大痛苦。基本思路是将“needer”类传递给“needable”类开始配置,配置结束后再将needer传回。 “需要”对象在内部设置。

例如:

ConfigUser cu = (new ConfigUser()).
cfgFavNum().twentySeven().increment().timesTwo().endCfg().
firstName("Kermit").lastName("Frog");

在哪里

firstName("Kermit").lastName("Frog")

是 ConfigUser 类的一部分,并且

twentySeven().increment().timesTwo().endCfg()

来自一个单独的“配置数字”类。 endCfg() 返回“needer”类 (ConfigUser),此时您应该能够在 ConfigUser 中继续返回链。但你不能。在下面的代码中......在我所做的每一次尝试中,我最终都会遇到同样的错误:

        C:\java\ConfigUser.java:4: cannot find symbol
symbol : method firstName(java.lang.String)
location: interface NeedsFavNum
cfgFavNum().twentySeven().increment().timesTwo().endCfg().
^

如果您注释掉 endCfg() 之后的所有内容,它会揭示问题:

ConfigUser cu = (new ConfigUser()).
cfgFavNum().twentySeven().increment().timesTwo().endCfg();//.
//firstName("Kermit").lastName("Frog");

C:\java\ConfigUser.java:15: incompatible types
found : NeedsFavNum
required: ConfigUser
cfgFavNum().twentySeven().increment().timesTwo().endCfg();//.
^

它不能返回 ConfigUser,它是 的子类 NeedsFavNum,它是所有“需要”的类的接口(interface)最喜欢的号码配置。

当然,您可以复制所有函数,以便它们全部返回 ConfigUser-s,但这违背了共享链的目的。目的是在任何类之间共享这些链,而不仅仅是子类。

有什么办法可以实现这个目标,或者重新考虑整个问题吗?我开始认为这根本不可能。

详细信息在下面的代码中。它有效(...直到出现这些编译错误为止):将其复制到名为 ConfigUser.java 的文件中并试一试。

谢谢你帮助我。

public class ConfigUser implements NeedsFavNum  {
public static final void main(String[] igno_red) {
ConfigUser cu = (new ConfigUser()).
cfgFavNum().twentySeven().increment().timesTwo().endCfg().
firstName("Kermit").lastName("Frog");

cu = (new ConfigUser()). cfgFavNum().twentySeven().increment().timesTwo().endCfg();//.
// firstName("Kermit").lastName("Frog");
}
//init
public static final int iDEFAULT_FAV = 8;
int iFav = -1;
String sName1st = null;
String sNameLast = null;
//funcs
public ConfigUser() {
}
public ConfigUser firstName(String s_s) {
sName1st = s_s;
}
public ConfigUser lastName(String s_s) {
sNameLast = s_s;
}
public FavNumConfigurator cfgFavNum() {
return new FavNumConfigurator(this, iDEFAULT_FAV);
}
public ConfigUser setNumReturnNeeder(int i_favFullyConfigured) {
iFav = i_favFullyConfigured;
return this;
}
}
interface NeedsFavNum {
ConfigUser setNumReturnNeeder(int i_fav);
}
class FavNumConfigurator {
NeedsFavNum nfn = null;
int iFav = -1;
public FavNumConfigurator(NeedsFavNum nf_n, int i_defaultFav) {
nfn = nf_n;
iFav = i_defaultFav;
}
public FavNumConfigurator twentySeven() {
iFav = 27;
}
public FavNumConfigurator timesTwo() {
iFav = iFav * 2;
}
public FavNumConfigurator increment() {
iFav += 1;
}
public NeedsFavNum endCfg() {
return nfn.setNumReturnNeeder(iFav);
}
}

具有工作代码的解决方案

事实证明,蜘蛛鲍里斯 (Boris the Spider) 的“GENERICS”评论正是我需要的线索。而不是“需要的”类

FavNumConfigurator

现在是

FavNumConfigurator<R extends FavNumNeeder>

其中 FavNumNeeder 是任何需要 Collection 号码配置链的类的“需要者”接口(interface)。现在 endCfg() 函数可以准确返回我想要的类。

这是固定示例(它可以工作——复制并保存为 ConfigUser.java):

/**
<P>The main class: the &quot;needer&quot;.</P>
**/
public class ConfigUser implements NeedsFavNum {
public static final void main(String[] igno_red) {
ConfigUser cu = (new ConfigUser()).
cfgFavNum().twentySeven().increment().timesTwo().timesTwo().endCfg().
firstName("Kermit").lastName("Frog");

System.out.println("name: " + cu.sName1st + " " + cu.sNameLast);
System.out.println("favorite-num: " + cu.iFav);

//---OUTPUT:
//name: Kermit Frog
//favorite-num: 112
}
//init
public static final int iDEFAULT_FAV = 8;
int iFav = -1;
String sName1st = null;
String sNameLast = null;
//funcs
public ConfigUser() {
}
//Self-returning configurers...START
public ConfigUser firstName(String s_s) {
sName1st = s_s;
return this;
}
public ConfigUser lastName(String s_s) {
sNameLast = s_s;
return this;
}
//Self-returning configurers...END
//Start fav-num configuration. Returns the "needable"
public FavNumConfigurator<ConfigUser> cfgFavNum() {
return (new FavNumConfigurator<ConfigUser>(this, iDEFAULT_FAV));
}
//Called by the "needable" in endCfg()
public ConfigUser setNumReturnNeeder(int i_favFullyConfigured) {
iFav = i_favFullyConfigured;
return this;
}
}

//The "needer" interface, for all classes needing favorite-number
//configuration
interface NeedsFavNum {
ConfigUser setNumReturnNeeder(int i_fav);
}

//The "needable" class: A shareable function-chain for favorite-number
class FavNumConfigurator<R extends NeedsFavNum> {
R nfn = null;
int iFav = -1;
public FavNumConfigurator(R nf_n, int i_defaultFav) {
nfn = nf_n;
iFav = i_defaultFav;
}
//Self-returning configurers...START
public FavNumConfigurator<R> twentySeven() {
iFav = 27;
return this;
}
public FavNumConfigurator<R> timesTwo() {
iFav = iFav * 2;
return this;
}
public FavNumConfigurator<R> increment() {
iFav += 1;
return this;
}
//Self-returning configurers...END
public R endCfg() {
nfn.setNumReturnNeeder(iFav);
return nfn;
}
}

通用的需求设计

这是我设计的实现上述修复的通用解决方案。最难的部分是避免 ConfigNeedableConfigNeeder 之间的循环依赖。

public interface Chainable  {
Chainable chainID(Object o_id);
Object getChainID();
}
public interface ConfigNeedable<O,R extends ConfigNeeder> extends Chainable {
boolean isAvailableToNeeder();
ConfigNeedable<O,R> startConfigReturnNeedable(R c_n);
R getActiveNeeder();
boolean isNeededUsable();
R endCfg();
}
public interface ConfigNeeder {
void startConfig();
boolean isConfigActive();
<O> Class<O> getNeededType();
<O> void setNeeded(O o_fullyConfigured);
}

这是使用此设计的相同(工作)示例,但由于它取决于我个人库中的实现(目前尚未发布,因为它在我处理它时每时每刻都在变化),它不会编译。希望它能帮助别人看到。

import  xbn.lang.chain.ChainableComposer;
import xbn.lang.chain.ConfigNeeder;
import xbn.lang.chain.SimpleConfigNeedable;
import xbn.lang.chain.SimpleConfigNeeder;

public class ConfigNeedableNeederXmpl {
public static final void main(String[] igno_red) {
UserSettings us = (new UserSettings()).
cfgFavInt().twentySeven().timesTwo().increment().endCfg().name("President Obama");
System.out.println("name=" + us.sName);
System.out.println("favorite number=" + us.iFav);
}
}
class UserSettings implements ConfigNeeder {
private SimpleConfigNeeder scn = new SimpleConfigNeeder(Integer.class);
public static final int iDEFAULT_FAV = 8;
public int iFav = -1;
public String sName = null;

public UserSettings name(String s_name) {
sName = s_name;
return this;
}
public FavNumConfigurator cfgFavInt() {
FavNumConfigurator fnc = new FavNumConfigurator();
fnc.startConfigReturnNeedable(this);
return fnc;
}
//ConfigNeeder: composition implementation...START
public <O> void setNeeded(O i_fullyConfigured) {
scn.setNeeded(i_fullyConfigured);
iFav = (Integer)scn.getElimNeeded();
}
public void startConfig() {
scn.startConfig();
}
public boolean isConfigActive() {
return scn.isConfigActive();
}
public <O> Class<O> getNeededType() {
return scn.getNeededType();
}
public void endConfig() {
iFav = (Integer)scn.getElimNeeded();
}
//ConfigNeeder: composition implementation...END
}
class FavNumConfigurator extends SimpleConfigNeedable<Integer,UserSettings> {
public FavNumConfigurator() {
super(33, true);
}
public FavNumConfigurator(Integer o_defaultNeeded, boolean b_defaultNeededUsable) {
super(o_defaultNeeded, b_defaultNeededUsable);
}
public FavNumConfigurator set(int i_i) {
try {
updateObject(i_i);
} catch(RuntimeException rtx) {
throw newRTXWChainID("set", rtx);
}
return this;
}
public FavNumConfigurator twentySeven() {
updateObject(27);
return this;
}
public FavNumConfigurator timesTwo() {
updateObject(getNeededInProcess() * 2);
return this;
}
public FavNumConfigurator increment() {
updateObject(getNeededInProcess() + 1);
return this;
}
}

最佳答案

您正在寻找的实际上是 C++ Curiously recurring template pattern .

您可以将所有“共享”的自返回位放在一个基本抽象类中,然后扩展它。

例如:

public abstract class Base<T extends Base<T>>
{
protected abstract T self();

protected String name;
protected String address;

public T withtName(String name)
{
this.name = name;
return self();
}

public T withAddress(String address)
{
this.address = address;
return self();
}

}

class MyClass extends Base<MyClass>
{
private String someOtherThing;

public MyClass withSomeOtherThing(String thing)
{
this.someOtherThing = thing;
return self();
}

@Override
protected MyClass self()
{
return this;
}
}

现在您可以:

MyClass mc = 
new MyClass()
.withAddress("111 elm")
.withtName("Bob")
.withSomeOtherThing("foo");

关于java - 如何与任何类共享自返回方法链?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20850578/

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