2014-01-22 4 views
2

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

Давайте предположим, что у меня есть этот класс

public class ASuperClass { 
    public abstract void doSomething(String arg1, Integer arg2); 
} 

Так что, если я тогда продлить выше класс, я бы тогда следующее, где я был бы вынужден отменить DoSomething со списком аргументов в строки и Integer.

public class ASubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer arg2){ 
     some code..... 
    } 
} 

Теперь давайте предположим, что в моем подклассу я прекрасно переопределить DoSomething, но мне нужно дополнительное Струнный ARG в моем подклассу. Итак, что я хотел бы сделать, это ниже:

public class ASubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer arg2, String arg3){ 
     some code... 
    } 
} 

выше не будет компилировать, хотя, потому что мой подкласс не реализует абстрактную подпись, определенный в базе. Таким образом, чтобы получить его для компиляции, я могу, конечно, сделать это:

public class ASubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer arg2){} 

    public void doSomething(String arg1, Integer areg2, String arg3){ 
     here is my code...... 
    } 
} 

Итак, что же я пытаюсь сделать вы, вероятно, спрашиваете? Меня интересует, есть ли способ «принудительно» любого подкласса класса, используя generics как arg, для реализации базового абстрактного метода, независимо от списка arg. Так что следующий будет компилировать расширения ASuperClass:

public class ASubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer areg2, String arg3){ 
     here is my code...... 
    } 
} 

public class AnotherSubClass extends ASuperClass{ 
    @Override 
    public void doSomething(String arg1, Integer areg2, String arg3, Integer arg4){ 
     here is my code...... 
    } 
} 

Таким образом, вы можете «родовое-Изе» список ARG базового класса, так что вышеупомянутые два класса будет составлять? Что-то вроде ниже? Я знаю, что приведенный ниже синтаксис неверен, но можете ли вы создать общий список arg?

public class ASuperClass { 
    public abstract void doSomething(<?>); 
} 

В целом, моя идея заключается в обеспечении согласованности в приложении, в котором люди расширяют некоторые базовые функции. В основном убедитесь, что в каждой подсистеме ASuperClass есть функция doSomething(), чтобы обеспечить согласованность (в частности, имя метода) по подклассам, но это список аргументов может отличаться для каждого подкласса.

Надеюсь, что это не слишком смущает. Заинтересован знать, возможно ли это.

+0

Это просто невозможно. И дженерики даже не могут прийти в картину. У вас должно быть два разных метода в подклассах. –

ответ

0

Параметры метода являются частью метода «подписи», который используется, чтобы решить, переопределение. Для того чтобы подкласс мог переопределить метод в своем базовом классе, реализовать абстрактный метод его абстрактного базового класса или реализовать метод интерфейса, вся подпись, включая типы параметров, должна соответствовать.

Если вы хотите, чтобы список аргументов, чтобы принимать переменное число параметров, вы можете использовать этот синтаксис:

public abstract void doSomething(Object ... args); 

Вы можете переопределить метод с этой подписью в подклассах, и вы можете передать стольких аргументов как хотите.Некоторое Печальное следствие этого дизайнерского решения является то, что

  • Ваших параметры теперь нетипизированный - каждый метод должен подтвердить свой список параметров, в том числе их типа, прежде чем приступить к расчетам, и
  • Параметров примитивные типы необходимо обернуть в Object s - примитивы должны быть в коробке или автобокс.
0
public class ASuperClass 
{ 
    public abstract void doSomething(Object ... args); 
} 

public class ASubClass extends ASuperClass 
{ 
    @Override 
    public void doSomething(Object ... args) 
    { 
     here is my code...... 
    } 
} 

Это позволит оба вызова: doSomething(str1, int1) и doSomething(str1, int1, str2, int2);

+0

Это то, о чем я думал. Так, это покрывает любой тип arg? Например, я мог бы в подклассе: @Override общественного недействительный йоЗотеЬЫпд (String arg1, Integer арг2, внутр arg3) { вот мой код ...... } Значения, будет elipses Object .... args обертки примитивных типов? Спасибо – tas2826

0

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

Например, посмотрите на этот пример кода.

List<ASuperClass> list = new ArrayList<ASuperClass>(); 
list.add(new ASubClass()); 
list.add(new AnotherSubClass()); 

Таким образом, мы создаем список объектов всех типа ASuperClass, а затем добавить два объекта в этот список. Эти объекты имеют разные типы, но оба они имеют общий общий родитель. Это означает, что мы можем гарантировать, что они будут реагировать на все сигнатуры методов в типе ASuperClass.

for(ASuperClass obj : list) 
{ 
    obj.doSomething("parm1", 1); 
} 

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

Как другие предположили, существует хакерский способ сделать это.

public abstract void doSomething(Object ... params); 

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

Если с другой стороны вам нужно переменное количество параметров одного и того же типа, вы можете использовать его более безопасно.

public abstract void doSomething(String parm1, Integer parm2, String ... params); 

В этом случае вам всегда потребуется строка, целое число, а затем переменное количество строк. Это действительно эквивалентно этому.

public abstract void doSomething(String parm1, Integer parm2, String[] params); 
Смежные вопросы