Java继承-使用相同方法的两个类
我有两个类,Java继承-使用相同方法的两个类,java,inheritance,casting,Java,Inheritance,Casting,我有两个类,ObjectA和ObjectB,它们都扩展了相同的类MasterObject。我还有一个接口,其中包含一个我希望ObjectA和ObjectB实现的方法。在主对象中找不到此方法。然后我有一个类,它有一个类型为MasterObject的字段,并希望访问ObjectA和ObjectB中的方法。这不需要铸造就可以吗?这是我的一些代码 此外,我无法更改主对象类 public interface MyInterface{ void doSomething(); } class Obj
ObjectA
和ObjectB
,它们都扩展了相同的类MasterObject
。我还有一个接口,其中包含一个我希望ObjectA
和ObjectB
实现的方法。在主对象
中找不到此方法。然后我有一个类,它有一个类型为MasterObject
的字段,并希望访问ObjectA
和ObjectB
中的方法。这不需要铸造就可以吗?这是我的一些代码
此外,我无法更改主对象
类
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()
似乎很有效,但有没有其他方法可以不用强制转换来实现这一点?有更干净的吗?最干净的方法是将接口的对象声明为类型:
MyInterface mObj;
您可以以相同的方式使用具体类实例化对象:
mObj = new ObjectA();
...
mObj = new ObjectB();
唯一的限制是,在没有强制转换的情况下,您只能调用
doSomething
方法,因为它是接口中定义的唯一方法。如果您只打算使用此方法,那就应该这样做。问题在于类MasterObject
没有实现接口MyInterface
,尽管他的孩子实现了
解决方案是实现接口:
MyInterface mObj;
mObj = new ObjectA();
最后一个解决方案是创建一个代理抽象类
AbstractMasterObject
,该类实现MyInterface
这将允许ObjectA
和ObjectB
拥有MasterObject
和MyInterface
的全部功能,如果它们扩展AbstractMasterObject
可以这样做:
public abstract class AbstractMasterObject extends MasterObject implements MyInterface{
}
然后您可以这样声明您的对象:
AbstractMasterObject a = new ObjectA();
AbstractMasterObject b = new ObjectB();
您在这里有一些选择,其中一些已经提到。您已经提到,不能将接口添加到
主对象中,并且交互比doSomething
更复杂。任何其他约束都可能决定哪一个最适合您
第一个选项是按照Craig的建议,创建中间的AbstractMasterObject
,以扩展MasterObject
,并实现MyInterface
。这是一种快速简便的方法,可以创建一个既是MasterObject
又是MyInterface
实例的引用。缺点是Main
现在必须使用AbstractMasterObject
而不是MasterObject
。因此它不能使用MasterObject
的任何其他子类。这可能根本不是问题,也可能完全破坏了交易。实际上,它介于两者之间
另一种选择是使用组合而不是继承。因此ObjectA
和ObjectB
都有MasterObject
的实例,而不是扩展它。然后,他们使用该引用访问MasterClass
行为(为了简单起见,我只是展示ObjectA
):
从这里开始,有几种不同的策略可以将其合并到Main
中。您可以在Main
中引用MasterClass
,并将其传递给ObjectA
构造函数。然后维护MasterClass
和MyInterface
参考:
class Main {
MyInterface myInterface;
MasterObject masterObject;
public void method1(){
masterObject = new MasterObject();
myInterface = new ObjectA(masterObject);
myInterface.doSomething();
masterObject.someMasterObjectMethod();
}
}
只有当ObjectA
既不重写MasterObject
方法也不访问任何受保护的成员时,这种方法才有效。在Main
和ObjectA
中引用相同的MasterObject
,也可能导致混淆。如果两个类都可以更改主对象的状态
,那么您可能会遇到一些棘手的错误。另一方面,如果这些都不是问题,那么这可能是一个好方法。它将MyInterface
添加到Main
而不中断MasterObject
,并间接使用MasterObject
实现MyInterface
或者您可以完全从Main
隐藏MasterObject
,并且仅通过MyInterface
进行交互。要做到这一点,您只需从getMasterObject
到MyInterface
。或者,您可以向MyInterface
中添加专门与Main
如何与之交互相关的方法。我认为这样的方法是最干净的,但它需要修改最多的代码。如果这主要是新的开发,那么重构可能是值得的。如果是较旧的代码,那么我倾向于采用侵入性较小的方法
另一个选择是从稍微不同的方向来实现这一点。您完全按照定义的方式使用这些类。不同之处在于,Main
同时有一个MasterObject
和MyInterface
引用指向同一个实例:
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
,同一个实例作为MyInterface
和MasterObject
执行是完全巧合的。我认为如果这是遗留代码,这种方法将是最好的,因为它是入侵性最小的。如果这是一个比较新的代码,那么我会考虑其他策略,然后诉诸这样的事情。还有其他方法,但我认为这应该是一个很好的概述。不管怎样,您都应该后退一步,思考这些类之间的关系到底是什么。这将帮助您找到正确的方向。您能够更改主对象类吗?@CraigR8806不,我不能。谢谢。这似乎有效。我尽可能地简化了我的问题,但事实是,有几种方法是共享的,我需要添加到接口中。代理是更好的方法
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();
}
}