我有一个像这样的对象列表
ArrayList <Page> pageList = aForeignObject.getAllPages();
和一个儿童班
class MyPage extends Page
{
public void newFunction()
{
// A new Feature
}
}
是否有可能以某种方式将Page对象转换为MyPage对象?
我很乐意这样做:
MyPage page = pages.get(1); // This will obviously fail
page.newFunction();
答案 0 :(得分:4)
如果来自Page
方法的getAllPages()
个对象实际上是MyPage
个对象,那么只需使用强制转换(例如MyPage page = (MyPage) pages.get(1);
。如果它们不是({1}}很可能,如果你使用的是外部代码),你就不能使用子类。但你可以做的是使用组合:
class MyPage{
private Page p;
public MyPage(Page aPage){
p = aPage;
}
public void newFunction(){
//stuff
}
public Object oldFunction(){
return p.oldFunction();
}
}
然后你可以做类似的事情:
MyPage page = new MyPage(pages.get(1));
page.newFunction();
答案 1 :(得分:1)
简短的解决方案是施放:
MyPage page = (MyPage)pages.get(1);
请注意,这要求所讨论的对象实际上是MyPage
类型 - 否则强制转换失败并显示ClassCastException
。如果您不确定,可以先检查对象的类型:
Page elem = pages.get(1);
if (elem instanceof MyPage) {
MyPage page = (MyPage)elem;
...
}
然而,做这种向下倾斜的需要通常表明你的班级设计可以改进。如果aForeignObject.getAllPages()
始终返回MyPage
个对象的列表,则应相应地更改其返回类型。否则,如果newFunction
在Page
的接口中有意义(即使是抽象或具有空的默认实现),您应该考虑在那里添加它;然后,您可以直接在newFunction
引用上调用Page
,而无需向下转发。 击>
更新,因此您实际拥有要转换为Page
个对象的MyPage
个对象......对此的技术解决方案是转换构造函数:
class MyPage extends Page {
MyPage(Page other) {
// deep copy internal state
}
...
}
虽然从技术上说这是有效的,但如果可能的话,我仍然会重新考虑需要这些解决方案的设计方法。如果您使用第三方代码,则无法更改,但这不是一个选项。
答案 2 :(得分:0)
这显然是凌乱但可以工作......
Page page = pages.get(1);
if (page instanceof MyPage) {
((MyPage)page).newFunction();
}
您可以保存extends
Page,即
List <? extends Page> pageList = aForeignObject.getAllPages(); //Bear in mind that Page objects will never be found here.
现在,如果列表中只包含MyPage,那么您可以使用上面的示例。就像我说的那样,它不是有效的,也不是一种有效的解决方案。
答案 3 :(得分:0)
我认为解决方案是在Page
中实施您的“新功能”。我之前也有过一些这样的情况,对我来说,在基类中实现它是解决方案。但我不确切知道你的情况究竟是什么......
第二种解决方案(不推荐):使您的“新功能”成为静态方法。像这样:
public static void feature(Page page)
{
....
}
然后,您可以在MyPage中创建一个快捷方式:
public void invokeFeatureMethod()
{
feature(this);
}