这个问题可能很简单(我希望不是),但我在一次采访中找到了。 通常,给定一个接口类IntClass,以及许多实现的接口,名为ImpIC1,ImpIC2,...,ImpICk。 IntClass中的方法是名为void action1(),void action2()...,void actionM()的抽象公共方法。
我得到了一个公共类Test,其公共静态函数名为:public static IntClass foo(IntClass c1,IntClass c2)。此方法对c1和c2执行一些操作以创建InClass并返回。 但是,该方法必须适用于IntClass 的每个有效实现。问题主要在于c3的定义。我如何设计方法foo()..
请参阅下面的代码详细信息:
public interface IntClass {
abstract void action1();
..
abstract void actionM();
}
...
public class ImpIC1 implements IntClass {
public void action1() { ... }
public void action2() { ....}
..
public void actionM() { ... }
}
...
public class ImpIC2 implements IntClass {
public void action1() { ... }
public void action2() { ....}
..
public void actionM() { ... }
}
...
public class ImpICk implements IntClass {
public void action1() { ... }
public void action2() { ....}
..
public void actionM() { ... }
}
...
public class Test {
public static IntClass foo(IntClass c1, IntClass c2) {
....
...
return c3;
}
}
...
问题主要在于c3的定义。我尝试了以下解决方案(没有一个工作):
答案 0 :(得分:1)
我不了解您的实施情况。但这里有一点我们需要知道。 您无法实例化接口(匿名内部类除外)。如果您希望Interface返回更改测试类,如下所示 -
public class Test {
public static IntClass foo(IntClass c1, IntClass c2,String className) {
....
...
IntClass c3 = Class.forName(className);
//Set properties of c3 as your logic.
return c3;
} }
答案 1 :(得分:1)
也许他们想知道你是否知道如何使用reflection来返回任何类c1
的实例。每个对象都是类的实例(甚至是匿名内部类)。您可以为引用类型提供接口,但最后它指向类实例。
public IntClass foo(IntClass c1, IntClass c2) {
IntClass c3 = c1.getClass().newInstance(); // requires no-arg constructor
// use c1 and c2 to set up c3 ...
return c3;
}
答案 2 :(得分:1)
发布的规格非常模糊。 “此方法对c1和c2执行一些操作以创建一个InClass并返回”。这根本没有指定任何功能要求。
以下解决方案对c1和c2执行了一些操作(它们是相当荒谬的操作,但规范并不禁止操作无意义)。它还会创建一个返回的新IntClass实例。并且,IntClass的任何实现都可以作为参数传递,并且该方法仍然有效。
public static IntClass foo(IntClass c1, IntClass c2){
c1.getClass();
c2.toString();
return new IntClass{
public void action1(){}
public void action2(){}
...
public void actionM(){}
};
}
现在,基于我对可能需求的猜测,我将提出另一个更明智的解决方案。这并不完全符合规定的要求,但我认为这可能是面试官所寻求的。
public class Test{
public static IntClass foo(IntClass c1, IntClass c2){
return new CompositeIntClass(c1, c2);
}
public class CompositeIntClass implements IntClass{
private IntClass c1;
private IntClass c2;
public CompositeIntClass(IntClass c1, IntClass c2){
this.c1 = c1;
this.c2 = c2;
}
public void action1(){
c1.action1();
c2.action1();
}
public void action2(){
c1.action2();
c2.action2();
}
...
public void actionM(){
c1.actionM();
c2.actionM();
}
}
}
使用此实现,调用foo(c1,c2)将正式不对c1或c2执行任何操作。所以它不符合规定的要求。但是,它将创建一个新的IntClass实例,其行为与c1和c2相结合。即在c3上调用action2()将在c1和c2上调用action2()。我认为这可能是要求应该是什么(只是猜测)。
总而言之,这意味着返回的对象(c3)将具有任意IntClass实现的行为。然而,这并不意味着你能够做SomeArbitraryImplClass c3 = (SomeArbitraryImplClass) foo(c1, c2);
,因为这样做会违反界面抽象的整个概念(肯定没有在面试中提倡的内容)。
解决方案是the Composite Pattern的一个例子。
<强>&LT;编辑&gt; 强>
如果您使用广义抽象,则必须确保它们与您打算用它们解决的问题兼容。由于所描述的问题设置中的所有actionI()方法都具有void返回类型,因此无法提取任何PairInterface实例的最小值和最大值(如注释中所述)。抽象不允许这样做。
如果这是您想要做的,那么解决方案就更简单了。 (这是基于PairInterface包含声明int getX()
和int getY()
的假设,这对于PairInterface来说似乎是合理的:)
public class Test{
public static PairInterface mix(PairInterface c1, PairInterface c2){
int minX = Math.min(c1.getX(), c2.getX());
int maxY = Math.max(c1.getY(), c2.getY());
return new SomePairInterfaceImplementation(minX, maxY);
}
}
除此之外,您还必须创建SomePairInterfaceImplementation
类,或者使用一些可以接受x和y作为构造函数参数的现有类。
请注意:
1)如果PairInterface
仅声明void方法,那么计算c1和c2的x值的最大值或最小值是不可能的。这些值被封装和隐藏,无法访问。
2)该方法返回的PairInterface的实现方式无关紧要。具有接口返回类型的原因是接口的任何一致实现都应该有效。
<强>&LT; /编辑&gt; 强>
答案 3 :(得分:0)
您可以使用匿名类创建接口对象并实现所有抽象方法:
IntClass c3 = new IntClass()
{
@Override
public void action1()
{
// ...
}
// ...
@Override
public void actionM()
{
// ...
}
};
答案 4 :(得分:0)
你确定你的问题是对的吗?从您对Eng.Fouad的评论
ImpClass3 s3 = foo(s1, s2)
没有意义。在右边有一些抽象的东西,在左边有一些具体的东西是错误的,通常它们反之亦然。这就像你点“任何东西吃,无论如何”,但期待“巨无霸鸡肉与可乐”:)