2013-05-16 6 views
3

я с трудом с созданием безопасного поведения типа, я буду использовать общий пример для того, чтобы подчеркнуть свой вопрос:Как вернуть реальный экземпляр из метода с общим типом возвращаемого

У меня есть интерфейс BoxCreator, который определяется по формуле:

public interface BoxCreator{ 
    public Box create(int id ,List<Box> others); 
} 

и общий Box класс (а Box может содержать несколько других Box ES), который имеет такие методы, как int getId(), Box getInternalBox(int id).

Предположим, у меня есть класс Shed implements BoxCreator,Container (где контейнер - это просто общий интерфейс с действием, например, добавление и удаление). Я могу положить новые вещи в сарай, и он будет короблять их в ShedBox, который реализует Box.

До сих пор так хорошо, проблема возникает, когда я пытаюсь сделать какой-нибудь другой класс, который будет делать вещи немного по-другому, к примеру CoolShed extends Shed implements BoxCreator, который положит вещь в CoolBox эс (которые проходят ShedBox).

На данный момент это работает, но у меня есть несколько подкладок в классе CoolShed (от общего Box до CoolBox), который может быть «не красивым».

Что я ищу способ сделать

Shed<T extends ShedBox> implements BoxCreator<T>

А потом, когда implemeting в CoolShed я бы просто сделать что-то вроде

CoolShed extends Shed<CoolBox> implemets BoxCreator<CoolBox>

Я пытался сделать разные классы родовыми, но не смог создать общий метод create, потому что я не могу создать экземпляр T или вернуть его на этот счет. Поэтому я немного потерялся.

Несколько нот:

  1. CoolShed использует много из Shed логики, но я бы просто, чтобы сделать его использовать CoolBox класс в качестве контейнера.
  2. В настоящее время Shed имеет экземпляр BoxCreator, поэтому при создании CoolShed я просто делаю CoolShed новым создателем, и он работает.
  3. CoolShed будет иметь только CoolBox экземпляров, но на самом деле я бы не прочь ничего простирающегося ShedBox в классе Shed.

Я просто не мог найти хорошее объяснение того, как достичь желаемого поведения, и я не мог сказать, являются ли мои существующие роли О.К.

Я знаю, что мой пример довольно длинный, я был бы счастлив сделать его более ясным в любом случае.

EDIT

шаблон кода, чтобы сделать вопрос яснее:

public interface BoxCreator{ 
    public Box create(int id ,List<Box> others); 
} 

public interface Box{ 
    void put() 
    void addAnother(Box box); 
} 

public class ShedBox implements Box{ 
    void put() 
    void addAnother(Box box); 
} 

public class CoolBox extends ShedBox{ //has some extra features but moslty the same 
    void put() 
    void addAnother(Box box); 
} 

public interface Container { 
    Box addValue(int value); 
    Box getBox(int id); 
    . 
    . 
} 

public class Shed implements Container, BoxCreator { 
    BoxCreator creator; 
    SomeCollection<Box> boxes; 
    Shed(){ 
     creator = this; 
     . 
     . 
     . 
    } 

    Box addValue(int id){ 
     . 
     .//some logic to get otherBox here 
     . 
     Box box = creator.createBox(id,otherBox); 
    } 

    Box getBox(int id); 

    public Box create(int id ,Box other){ 
     return new ShedBox(id,others) 
    } 
} 

public class CoolShed extends Shed implements BoxCreator { 

    CoolShed(){ 
     creator = this; 
     . 
     . 
     . 
    } 

    addValue(int id){ 
     Box boxAdded = super.add(id) 
     . 
     . 
     . 
     CoolBox box = (CoolBox)boxAdded; // The questionable cast 
     . 
     . //Some logic that involves CoolBox specific actions 
     . 
    } 

    public Box create(int id ,Box other){ 
     return new CoolBox(id,others) 
    } 

} 
+0

Возможно, лучше включить образец кода с различными классами, чтобы показать, чего вы пытаетесь достичь ... –

+0

Может ли CoolShed содержать CoolBox или может содержать любую коробку? –

+0

@owlstead это много (доверять мне :)) кода, и большинство из них не имеет отношения к проблеме, поэтому я боюсь, что это только смутит людей еще больше, но я сделал несколько общих шаблонов, которые могли бы объяснить проблему лучше. – SadStudent

ответ

0

(Предыдущий ответ удален)

EDIT: Это решение должно быть лучше, если предположить, others может содержать любое поле :

public interface BoxCreator { 
    public Box create(int id, List<Box> others); 
} 
public class Shed implements BoxCreator { 
    @Override 
    public ShedBox create(int id, List<Box> others) { 
     ... 
    } 
} 
public class CoolShed extends Shed { 
    @Override 
    public CoolBox create(int id, List<Box> others) { 
     ... 
    } 
} 

Кроме того, не делайте этого:

BoxCreator creator; 
creator = this; 
creator.create(...); 

Вместо этого, вы должны либо написать this.create(...) или просто create(...). Тогда вам не нужно будет отбрасывать от Box до нужного подкласса, так как значение, возвращаемое с create, уже будет иметь тип ShedBox или CoolBox.

+0

Я действительно пробовал эту опцию, но я не мог вернуть 'новый ShedBox()' из 'create', возможно, мое обновление может сделать мою ситуацию более ясной. – SadStudent

+0

@owlstead Я считал использование 'B', поскольку все они являются экземплярами« Box », но решили просто пойти с' T'. –

+0

@Lonenebula Спасибо, но при использовании 'public Box create (...)' в качестве сигнатуры реализации он выдает предупреждение «unchecked overriding: тип возвращаемого типа требует немедленного преобразования», а при использовании «непроверенный вызов» создается как необработанный тип BoxCreator ". Использование 'public T create (...)' не компилируется .. – SadStudent

Смежные вопросы