2

Доброго времени суток. Есть класс с полями, он имлементирует интерфейс с некоторыми методами. В новой классе создается список. Возможна ли следующая запись создания списка(1). Если да, то как обращаться к элементу такого списка?

 public interface MyInt{
  void getSmth();
  }

 public class MyClass implements MyInt{
  public String name;
  public Integer age;

  @Override
  public void get(){
  ....
   }

  public class Work{
 (1) private static List<MyInt> list = new LinkedList<>();
HiHello
  • 355
  • Возможна ли следующая запись создания списка - в принципе так и создаются списки и объекты......... как обращаться к элементу такого списка? - а что именно смущает? можно по индексу брать, к примеру. – Алексей Шиманский Nov 01 '17 at 16:42
  • просто не обычно что на основе интерфейса создается коллекция, и как например заполнить такую коллекцию. – HiHello Nov 01 '17 at 16:47
  • по поводу "необычно" - Почему необходимо инициализировать коллекции именно так? ...........как например заполнить такую коллекцию - как обычно, например list.add(new MyClass()) только желательно конструктор иметь у MyClass, чтоб инициализировать поля сразу – Алексей Шиманский Nov 01 '17 at 16:47
  • я имею в виду что в <> интерфейс ничего не имеющий в себе – HiHello Nov 01 '17 at 17:06
  • там не интерфейс.................. в нужный момент, когда необходимы методы класса MyClass нужно просто "кастовать" к нему, например System.out.println(((MyClass)list.get(0)).name); – Алексей Шиманский Nov 01 '17 at 17:10

3 Answers3

1

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

private static List<MyInt> list = new LinkedList<>();

private static void main(...) {
     list.add(new MyClass());
     list.add(new MyClass());
     MyClass obj = (MyClass) list.get(0); // плохой код (даже при проверки перед этим на instanceof)
     String name = obj.getName();
}

Намного правильнее сделать новый интерфейс в котором будут все нужные поля или просто хранить MyClass вместо интерфейса. Если вам в коллекции нужны только методы интерфейса, то все проще

private static void main(...) {
     list.add(new MyClass());
     list.add(new MyClass());
     MyInt obj = list.get(0); // нормальный код
     obj.getSmth();
}
  • Когда кастование стало признаком плохого кода? – Алексей Шиманский Nov 01 '17 at 17:21
  • 1
    Если в нем нет смысла - всегда. Какой смысл от статических типов, если вы получаете ошибки в рантайме и какой смысл от наследования и интерфейсов, если вы начинаете кастовать вручную? Да иногда без него не обойтись, но всегда когда есть возможность решить задачу без кастования - лучше решать без. То есть варнинги в Java при кастовании для вас хороший тон? А вариниг в случае выше будет; – Slava Vedenin Nov 01 '17 at 17:24
  • Если класс реализует несколько интерфейсов и имеет свои поля и методы, а в какой-то момент нужно пробежаться по коллекции объектов которые реализуют конкретный интерфейс, но вытащив параллельно поля класса - рекомендуете в каждом интерфейсе насоздавать поля такие на всякий случай? Не кажется это ерундой? – Алексей Шиманский Nov 01 '17 at 17:25
  • тут стоит подумать. а точно ли нужна такая коллекция мало связанных объектов? Может лучше иметь несколько коллекций конкретных классов или HashMap<тип, коллекция> 2) это как раз тот случай, когда плохо, но придется использовать кастинг. Пока этого можно избежать - лучше избегать
  • – Slava Vedenin Nov 01 '17 at 17:30
  • 1
    Вытащив параллельно поля класса - какого класса? Всё, что гарантирует коллекция - объявленный интерфейс, знание того, какие конкретно объекты там лежат - признак плохой архитектуры. – vp_arth Nov 01 '17 at 17:32
  • В соседнем ответе привел ссылки за статьи известных авторов, википедию (знаю, что не все ей доверяют, но там тоже есть список источников) на русском и английском – Slava Vedenin Nov 01 '17 at 21:48
  • 1
    Кастование - признак плохого кода просто потому, что тут 2 варианта: 1)вы кастуете заранее зная, что к родителю приведены объекты одного класса, тогда смысла в интерфейсе нет, потому как это фактически означает, что интерфейс импелементирует единственный класс, но при этом интерфейс на вмещает всех методов этого класса, это старнно, 2) у вас много наследников и вы кастуете,но теперь вы просто не знаете, что именно за объект приведен к интерфейсу,а значит у вас в коде появляется один из самых медленных операторов инстансоф.Чем больше потомков,тем больше свитч инстансоф, так до бесконечности... – Дмитрий Nov 01 '17 at 22:51