Java 两个使用相同方法的类



我有两个类,ObjectAObjectB都扩展了相同的类MasterObject。我还有一个接口,其中包含我希望ObjectAObjectB都实现的方法。在MasterObject中找不到此方法。然后我有一个类,它有一个MasterObject类型的字段,并且想要访问ObjectAObjectB中的方法。没有铸造可以吗?这是我的一些代码。

此外,我无法更改MasterObject类。

public interface MyInterface{
void doSomething();
}
class ObjectA extends MasterObject implements MyInterface {
@Override
public void doSomething(){
//...
}
}
class ObjectB extends MasterObject implements MyInterface {
@Override 
public void doSomething(){
//...
}
}
class Main {
MasterObject mObj;
public void method1() {
mObj = new ObjectA();
mObj.doSomething();
}
public void method2() {
mObj = new ObjectB();
mObj.doSomething(); //runs code from ObjectB class
}
}

现在这显然引发了一些编译器问题。(无法解析方法 doSomething(((。

像这样铸造:((ObjectA) mObj).doSomething();似乎有效,但是有没有另一种方法可以在不铸造的情况下做到这一点?有什么更干净的东西吗?

最终的解决方案是创建一个AbstractMasterObject实现MyInterfaceObjectAObjectB具有MasterObjectMyInterface的完整功能AbstractMasterObject

这可以像这样完成:

public abstract class AbstractMasterObject extends MasterObject implements MyInterface{
}

然后你可以像这样声明你的对象:

AbstractMasterObject a = new ObjectA();
AbstractMasterObject b = new ObjectB();

最干净的方法是将带有接口的对象声明为类型:

MyInterface mObj;

您可以使用相同的方式使用具体类实例化对象:

mObj = new ObjectA();
...
mObj = new ObjectB();

唯一的约束是 - 没有强制转换 - 您将只能调用doSomething方法,因为它是接口中定义的唯一方法。如果您打算仅使用此方法,则可以使用此方法。

问题是MasterObject的类没有实现接口MyInterface,尽管他的孩子实现了。

解决方案是实现接口:

MyInterface mObj;
mObj = new ObjectA();

你在这里有几个选项,有些已经提到过了。您已经提到无法将界面添加到MasterObject,并且交互比doSomething更复杂。任何其他限制都可能决定哪个最适合您。

第一种选择是按照克雷格的建议进行操作,并创建中间AbstractMasterObject来扩展MasterObject并实现MyInterface。这是一种快速简便的方法,可以同时具有MasterObjectMyInterface实例的单个引用。缺点是Main现在必须使用AbstractMasterObject而不是MasterObject.所以它不能使用MasterObject的任何其他子类。这可能根本不是问题,也可能是一个完全的交易破坏者。实际上,它介于两者之间。

另一种选择是使用组合而不是继承。因此,ObjectAObjectB各有一个MasterObject实例,而不是扩展它。然后他们使用该引用来访问MasterClass行为(为简洁起见,我只是显示ObjectA(:

class ObjectA implements MyInterface {
private masterObject masterObject; 
public ObjectA(MasterObject masterObject){
this.masterObject = masterObject;
}
@Override
public void doSomething(){ /* Implementation */ }
}

从这里开始,有几种不同的策略可以将其合并到Main。您可以在Main中引用MasterClass,并将其传递给ObjectA构造函数。然后维护MasterClassMyInterface引用:

class Main {
MyInterface myInterface;
MasterObject masterObject;
public void method1(){
masterObject = new MasterObject();
myInterface = new ObjectA(masterObject);
myInterface.doSomething();
masterObject.someMasterObjectMethod();
}
}

仅当ObjectA既不重写MasterObject方法也不访问任何受保护的成员时,此方法才有效。这也可能导致在MainObjectA中都引用同一MasterObject的混淆。如果两个类都可以更改MasterObject的状态,那么您最终可能会遇到一些棘手的错误。另一方面,如果这些都不是问题,那么这可能是一个好方法。它在不中断MasterObject的情况下为Main增加了MyInterface,并间接使用MasterObject来实现MyInterface

或者,您可以完全隐藏MasterObjectMain并仅通过MyInterface进行交互。为此,您只需getMasterObjectMyInterface即可。或者,您可以向MyInterface添加专门与Main如何与之交互的方法。我认为这样的方法最干净,但它涉及更改最多的代码。如果这主要是新的开发,那么可能值得努力重构。如果是较旧的代码,那么我倾向于侵入性较小的方法。

另一种选择从稍微不同的方向接近这一点。您可以完全按照定义的方式使用这些类。不同之处在于,Main具有指向同一实例的MasterObjectMyInterface引用:

class Main {
private MasterObject masterObject;
private MyInterface myInterface;
public void method1(){
ObjectA objectA = new ObjectA();
masterObject = objectA; // Legal because ObjectA extends MasterObject
myInterface = objectA; // Legal because ObjectA implements MyInterface
myInterface.doSomething(); // This does ObjectA's implementation
masterObject.someMasterObjectMethod();
}
}

所以Main,同一个实例执行MyInterfaceMasterObject完全是巧合。我认为如果这是遗留代码,这种方法将是最好的,因为它的侵入性最小。如果这是相对较新的代码,那么我会在诉诸这样的东西之前考虑其他策略。还有其他方法,但我认为这应该是一个很好的概述。无论如何,你应该退后一步,想想这些类之间的关系到底是什么。这应该有助于为您指明正确的方向。

最新更新