2010-09-08 6 views
3

Я получил список объектов, как этотРасширение класса в Java

ArrayList <Page> pageList = aForeignObject.getAllPages(); 

И класс ребенка

class MyPage extends Page 
{ 

    public void newFunction() 
    { 
     // A new Feature 
    } 
} 

возможно ли это каким-то образом преобразовать объекты страницу в объекты MYPAGE?

Я хотел бы сделать что-н, как это:

MyPage page = pages.get(1); // This will obviously fail 
page.newFunction(); 
+0

@ Программисты C++: Является ли это то, что мы можем сделать с 'dynamic_cast'? –

+0

@Martijn - Нет, динамический прилив будет только повышать преобразование, если класс относится к типу (или подтипу) класса, в который вы конвертируете. –

ответ

1

Короткий раствор литья:

MyPage page = (MyPage)pages.get(1); 

Обратите внимание, что это требует, чтобы рассматриваемый объект действительно типа MyPage - в противном случае литье заканчивается с ClassCastException. Если вы не уверены в этом, вы можете проверить тип объекта: первый

Page elem = pages.get(1); 
if (elem instanceof MyPage) { 
    MyPage page = (MyPage)elem; 
    ... 
} 

Однако необходимость делать такие downcasts часто является признаком, что ваш дизайн класс может быть улучшен. Если aForeignObject.getAllPages() всегда возвращает список объектов MyPage, вы должны соответствующим образом изменить его тип возврата. В противном случае, если newFunction имеет смысл в интерфейсе Page (даже как абстрактное или с пустой реализацией по умолчанию), вы должны рассмотреть возможность его добавления; то вы можете позвонить newFunction прямо на Page ссылки, не требуя понижения.

Update: так что вы на самом деле есть Page объекты, которые вы хотите преобразовать в MyPage объектов ... Техническое решение это было бы преобразующий конструктор:

class MyPage extends Page { 
    MyPage(Page other) { 
    // deep copy internal state 
    } 
    ... 
} 

Хотя технически это я бы все еще пересмотрел проектный подход, который требует таких решений, если это возможно. Если вы используете сторонний код, который вы не можете изменить, это не вариант.

+0

К сожалению, объект является экземпляром страницы, а не MyPage. – Jan

+0

. Мне бы хотелось добавить функцию на страницу, однако она является частью зарубежной библиотеки. Я также не знаю, как достичь внутреннего состояния «реального» объекта страницы. – Jan

+1

@Jan, тогда я боюсь, что у вас нет другого выбора, кроме подхода [decorator] (http://en.wikipedia.org/wiki/Decorator_pattern), предложенного @Scott. В качестве дополнительной заметки, включая всю эту информацию в вашем исходном сообщении, а не в комментариях, мы сохранили бы всех нас в бесполезной типизации ... –

4

Page Если объекты, выходящие из метода getAllPages() фактически MyPage объекты, а затем просто использовать бросок (например MyPage page = (MyPage) pages.get(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(); 
+0

Я думал об этом решении, однако мне пришлось бы написать 50 «старых» функций и их изменить каждый раз, когда изменяется класс страницы. – Jan

+0

Как сделать его явной оболочкой, тогда - создать общедоступный метод 'Page getOldPage()', который позволяет вызывать старые методы напрямую. – Scott

+0

Угадайте, я сделаю это. Думал, что может быть лучший способ. – Jan

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, то вы можете использовать мой пример выше. Как я уже сказал, это неэффективно и не является эффективным решением.

0

Я думаю, что решение заключается в реализации вашей «новой функции» в Page. У меня также были некоторые из этих ситуаций до и для меня, реализация этого в базовом классе была решением. Но я точно не знаю, в какой ситуации вы ...

Второе решение (не рекомендуется): сделайте свою «новую функцию» статическим методом. Что-то вроде этого:

public static void feature(Page page) 
{ 
    .... 
} 

Затем вы можете сделать ярлык в MyPage:

public void invokeFeatureMethod() 
{ 
    feature(this); 
} 
Смежные вопросы