java如何与任何类共享自返回方法链?
更新:我明白了!原来蜘蛛鲍里斯的“泛型”评论正是我需要的线索
首先是原始问题和中断的代码,下面是解决方案。下面是我为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
的子类,它是所有“需要”最喜爱的数字配置的类的接口
当然,您可以复制所有函数,以便它们都返回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);
}
}
具有工作代码的解决方案
原来蜘蛛鲍里斯的“泛型”评论正是我需要的线索。而不是“需要的”类
FavNumConfigurator
现在是
FavNumConfigurator<R extends FavNumNeeder>
其中FavNumNeeder是任何需要favorite number配置链的类的“needer”接口。现在endCfg()
函数可以准确地返回我想要的类
下面是一个固定的示例(它可以工作——复制并保存为ConfigUser.java):
/**
<P>The main class: the "needer".</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;
}
}
通用针刺可需设计
下面是我设计的一个实现上述修复的通用needer-needable解决方案。最困难的部分是避免ConfigNeedable
和ConfigNeeder
之间的循环依赖
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;
}
}
# 1 楼答案
你所要寻找的是有效的C++ Curiously recurring template pattern。
您可以将所有“共享”自返回位放入一个基本抽象类中,然后对其进行扩展
例如:
现在您可以执行以下操作: