1. Java / Говнокод #16498

    +123

    1. 1
    public <T extends IOrderSubmitRequest & IApiStoreRef> Order buildOrderFromSubmitRequest(final T request) { ... }

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

    Запостил: someone, 07 Августа 2014

    Комментарии (27) RSS

    • Ну, тут может возникнуть один интересный момент: например, оба интерфейса хотят один и тот же метод реализовать, как компилятор с таким поворотом событий обойдтестя? Ничего?

      Или, еще может быть, что объекты такого типа нереализуемы (в Яве ж нельзя явно выбрать метод какого интерфейса реализуется, или я не прав?), в принципе, или компилер такое не проверит?
      Ответить
      • Методы с одинаковой сигнатурой всегда сливаются, это вполне допустимо. Семантические различия остаются на совести погромистов.
        Ответить
        • Ну а если, например, один интерфейс хочет void foo(T); а второй void foo(K extends T); - так тоже покатит?
          Ответить
          • Если T и K - это разные конкретные типы, то нужно будет реализовать два метода.

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

            error: name clash: <K>apply(K) in Foo and apply(T#2) in A have the same erasure, yet neither overrides the other
            Ответить
            • Т.е. в Яве можно:
              class Foo {
              void foo(Foo foo) { }
              }
              class Bar extends Foo {
              void foo(Bar bar) { }
              }

              Не то, чтобы это сильно кому-то мешало, но ковырянтность там всякая...
              Ответить
              • Так это два разных перегруженных метода. Если дописать @Override к foo(Bar), не должно компилироваться.
                Ответить
        • Или даже так: Foo foo(Bar bar); Bar foo(Bar bar), где Foo extends Baz и Bar extends Baz, но не Foo extends Bar и не Bar extends Foo. Т.е. разные ветки наследования.
          Ответить
          • > Foo foo(Bar bar); Bar foo(Bar bar)
            Забреет, т.к. в одном классе не могут быть 2 метода с одинаковыми аргументами и разными возвращаемыми типами.

            > один интерфейс хочет void foo(T); а второй void foo(K extends T)
            Хрен знает, если честно... Я не помню как перегружаются дженерики. Ждем жабистов.
            Ответить
      • А в яве всё тупо - совершенно не важно сколько раз в реализуемых классом интерфейсах встречается одинаковый метод. Единственная его реализация будет видна через все интерфейсы.
        public interface Foo {
            public void test();
        }
        public interface Bar {
            public void test();
        }
        public class Impl implements Foo, Bar {
            public void test() {
                // ... будет вызываться и через Foo и через Bar ...
            }
        }
        Ответить
        • а типа
          public class Impl implements Foo, Bar {
              public void Foo.test() {
                  
              }
           public void Bar.test() {
                 
              }
          }


          нельзя?
          Ответить
          • Нельзя, это вам не .NET.
            Ответить
            • пичалька. А какой метод официальный?
              Ответить
              • >пичалька.
                А оно тебе надо?
                Ответить
                • Вдруг понадобиться жаба. Ну там под ведроид писать, все такое. Хотя уже есть хамарин
                  Ответить
                  • В смысле явные методы реализации интерфейсов, а не ява.
                    Всё-же - не явные преобразования и явные реализации методов интерфейса - достаточно опасная вещь.
                    И надо 10 раз подумать, а действительно-ли оно надо...
                    Ответить
                    • нет, я хотел узнать как нормально ограниччить метод, что бы он принимал обьекты класса который реализует несколько интесфейсв
                      Ответить
                      • > нет, я хотел узнать как нормально ограниччить метод, что бы он принимал обьекты класса который реализует несколько интесфейсв

                        Единственное решение в Жабе, где нет нормальных типов-пересечений, приведено в оригинальном посте. В каком-нибудь Ceylon это писалось бы красивее:

                        shared Order buildOrderFromSubmitRequest(IOrderSubmitRequest&IApiStoreRef request) { ... }
                        Ответить
                        • > В каком-нибудь Ceylon это писалось бы красивее

                          Да, вот теперь НАМНОГО красивее.
                          Ответить
        • https://ideone.com/IR6Gxe
          Ответить
    • А в чём, собственно, говно?
      Ответить

    Добавить комментарий