Возврат экземпляра класса в метод - PullRequest
0 голосов
/ 20 февраля 2012

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

Например:

Абстрактный класс A объявляет метод (method1), который должен возвращать экземпляр «List» классы B и C расширяют A. Я хочу, чтобы B возвратил ArrayList, а C - LinkedList.

Как я могу это реализовать? Спасибо

Ответы [ 6 ]

6 голосов
/ 20 февраля 2012

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

Это будет выглядеть примерно так:

public abstract class A<T extends List<String>> {
    public abstract T method()
}

public class B extends A<ArrayList<String>> {
    public ArrayList<String> method() {
        //...
    }
}

public class C extends A<LinkedList<String>> {
    public LinkedList<String> method() {
        //...
    }
}

Или, если вы собираетесь взаимодействовать с B и C напрямую (не через A), то вы можете использовать ковариантные типы возврата и просто сделать, чтобы подклассы объявляли тип возврата как ArrayListи LinkedList соответственно.В Java 5+ допустимо сужать тип возвращаемого значения переопределенного метода.

Если конкретный тип не должен быть известен вызывающей стороне, то вы просто хотите передать стратегию (то есть фабрику)) для создания списка на A.Это можно сделать, реализовав простой интерфейс:

public interface ListFactory<T> {

    public List<T> newList();
}

и затем передав его в конструктор A.Фактически фабрика может использоваться в любом случае, однако вам нужны только классы B и C, если вы находитесь в первой описанной мной ситуации.

1 голос
/ 20 февраля 2012
  public abstract class A<T> {
    public abstract List<T> getList();
  }

  public class ArrayListB extends A<String> {
    public List<String> getList(){
      return new ArrayList<String>();
    }
  }

  public class LinkedListC extends A<String> {
    public List<String> getList(){
      return new LinkedList<String>();
    }
  }
1 голос
/ 20 февраля 2012

На самом деле это называется шаблоном фабричного метода.

abstract class A{
    abstract public List<A> getList();
}

class B extends A{
    public List<A> getList(){return new ArrayList<A>();}
}

class C extends A{
    public List<A> getList(){return new LinkedList<A>();}
}
1 голос
/ 20 февраля 2012

Это довольно просто.Ключ в том, что подкласс может переопределить / реализовать, используя более узкий тип (ы), чем переопределенный / реализованный метод в суперклассе (тип возвращаемого значения, параметры и выброшенные исключения)

public abstract class A<T> {
    public List<T> getList();
}

public class B<T> extends A<T> {
    public ArrayList<T> getList() {
        // some impl
    }
}

public class C<T> extends A<T> {
    public LinkedList<T> getList() {
        // some impl
    }
}

ЗдесьЯ набрал класс с типом элемента в списке.

1 голос
/ 20 февраля 2012

Так просто, как это:

abstract class A {
    abstract List<Integer> method1();
}

class B extends A {
    @Override
    public LinkedList<Integer> method1() {
        return new LinkedList<Integer>();
    }
}

Это, конечно, не делает неправильное решение Марка Питера, это просто более простой способ начать imho.

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

abstract class A<T> {
    abstract List<T> method1();
}

class B<T> extends A<T> {
    @Override
    public LinkedList<T> method1() {
        return new LinkedList<T>();
    }
}
1 голос
/ 20 февраля 2012

Have A возвращают интерфейс типа Collection (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html) И LinkedList, и ArrayList реализуют этот интерфейс, так что B и C могут возвращать необходимые типы.

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