Здравствуйте, Qbit86, Вы писали:
C>>Вот за каким хреном так сделали?
Q>Представь, что у тебя твой TestClass реализует не только интерфейс ITest, но и ICompletelyDifferentInterface: Q>
java: types test.Test.I1 and test.Test.I2 are incompatible;
class test.Test.TestClass inherits unrelated defaults for method() from types test.Test.I1 and test.Test.I2
static class TestClass implements I1, I2 {
@Override
public void method() {
I1.super.method();
}
}
Здравствуйте, Codealot, Вы писали:
C>Если у тебя такое произойдет, к какому интерфейсу приведешь — такой и должен быть вызван.
Основная мотивация, стоящая за default interface methods — чтобы можно было добавлять методы в интерфейс, не ломая компиляцию существующих имплементоров.
Если ты автор библиотеки и добавляешь в интерфейс метод, то раньше у тебя все пользователи, реализующие интерфейс, ломались; и им нужно было определить у себя добавленный метод.
С добавлением default interface methods — нет, больше не ломаются, и явно реализовывать новый API им не требуется.
Представь, что твой класс TestClass реализует интерфейс ITest с методом Method() и интерфейс ICompletelyDifferentInterface без метода Method().
И потом автор второго интерфейса добавляет туда свой независимый метод Method().
Если использовать текущий подход C#, то есть изначально требовать явное приведение к нужному типу, то никакой неоднозначности не возникнет, и компиляция клиента не сломается.
Если по умолчанию разрешать вызов без приведения, то добавление нового метода Method() сломает компиляцию, то есть defeats the whole idea.
Здравствуйте, Qbit86, Вы писали:
Q>Если ты автор библиотеки и добавляешь в интерфейс метод, то раньше у тебя все пользователи, реализующие интерфейс, ломались; и им нужно было определить у себя добавленный метод. Q>С добавлением default interface methods — нет, больше не ломаются, и явно реализовывать новый API им не требуется.
Только в некотором подклассе случаев.
Q>Если по умолчанию разрешать вызов без приведения, то добавление нового метода Method() сломает компиляцию, то есть defeats the whole idea.
С фига ли? В большинстве случаев, таких проблем не будет.
defeats the whole idea — это когда у тебя производный класс не умеет то, что умеет базовый.
Ад пуст, все бесы здесь.
Re[2]: default interface methods. Какой все же бред.
Здравствуйте, vsb, Вы писали:
vsb>В жаве работает. А почему в C# ошибка?
Видимо, потому что опять кто-то допустил детишек-переростков до работы взрослых.
does not contain a definition for 'Method' and no accessible extension method 'Method' accepting a first argument of type 'Program.TestClass' could be found
Я не очень понял, в пользу какого тезиса ты приводишь этот пример.
(Джаву я не знаю, поверю написанному на слово.)
В твоём примере, чтобы был доступен метод method() в конкретном наследнике, пришлось его в этом наследнике реализовать, и вызвать там базовый метод, явно указав из какого предка его взять.
Такое и в C# будет работать, пример топик стартера был другой и не про это.
Здравствуйте, Codealot, Вы писали:
vsb>>В жаве работает. А почему в C# ошибка?
C>Видимо, потому что опять кто-то допустил детишек-переростков до работы взрослых.
Так ведь в приведённом примере на Джаве ещё хуже, там будет ошибка компиляции не на попытке вызова метода method(), а ещё на этапе попытки определить имплементора двух интерфейсов без явной реализации метода method():
java: types test.Test.I1 and test.Test.I2 are incompatible;
class test.Test.TestClass inherits unrelated defaults for method() from types test.Test.I1 and test.Test.I2
Здравствуйте, Codealot, Вы писали:
C>С фига ли? В большинстве случаев, таких проблем не будет.
Проблема будет в каждом таком случае, если в интерфейс добавляется метод, который уже есть в других реализуемых интерфейсах.
C>defeats the whole idea — это когда у тебя производный класс не умеет то, что умеет базовый.
Здравствуйте, Qbit86, Вы писали:
Q>Проблема будет в каждом таком случае, если в интерфейс добавляется метод, который уже есть в других реализуемых интерфейсах.
Была, есть и будет есть. Не будет ее только в одном подклассе случаев — когда ты добавляешь метод, для которого можно написать дефолтную реализацию, которая имеет смысл по условиям задачи.
Q>Так он умеет — если работаешь через абстракцию.
Здравствуйте, Qbit86, Вы писали:
Q>Так ведь в приведённом примере на Джаве ещё хуже, там будет ошибка компиляции не на попытке вызова метода method(), а ещё на этапе попытки определить имплементора двух интерфейсов без явной реализации метода method():
Здравствуйте, Codealot, Вы писали:
Q>>Так ведь в приведённом примере на Джаве ещё хуже, там будет ошибка компиляции не на попытке вызова метода method(), а ещё на этапе попытки определить имплементора двух интерфейсов без явной реализации метода method():
C>А, так ты из любителей маскировать ошибки?
А у тебя и нет ошибки, если ты работаешь через абстракции — через ITest или через <TTest> where TTest : ITest. В C# ты это сделать можешь. В Джава (если верить написанному) — нет, потому что она даже не даст тебе определить имплементора.
C>А, так ты из любителей маскировать ошибки?
А, так ты из виртуалов Kolesiki, что ли? Я тогда не будут тратить на тебя время.
Здравствуйте, Qbit86, Вы писали:
vsb>>работает
Q>Я не очень понял, в пользу какого тезиса ты приводишь этот пример.
В пользу тезиса, что ромбовидное наследование является разрешимой проблемой.
Q>Такое и в C# будет работать, пример топик стартера был другой и не про это.
Здравствуйте, Qbit86, Вы писали:
Q>Представь, что у тебя твой TestClass реализует не только интерфейс ITest, но и ICompletelyDifferentInterface: Q>Метод Method() какого интерфейса по-твоему должен быть вызван в вызове `obj.Method()`?
Ты вот такую дурь пишешь, что не сразу поймёшь, что ты умный
Что значит "представь"?? Тебе УЖЕ ДАЛИ ЗАДАЧУ. Ясную как день. Что тебе ещё в ней непонятно? Есть класс, есть метод из интерфейса. И он ОБЯЗАН работать. По кр. мере по программерской логике. А теперь ты выдумываешь СВОЙ пример и что-то начинаешь доказывать. Зачем? Ответь на оригинальный вопрос!
Здравствуйте, Qbit86, Вы писали:
Q>Основная мотивация, стоящая за default interface methods — чтобы можно было добавлять методы в интерфейс, не ломая компиляцию существующих имплементоров.
Хм... а это что за идиотизм?? С чего бы это изменённый предок "не должен" ломать наследников? ЕЩЁ КАК ДОЛЖЕН!!
Если у тебя класс "ГеомФигура" и ты помимо "Площадь" добавил метод "Периметр", все наследники обязаны реализовать правильный метод "Периметр"!
Собственно, потому интерфейс и является КОНТРАКТОМ, что там нет "отлынивающих классов" — любой из наследников ОБЯЗАН корректно реализовать контракт.
Q>Если ты автор библиотеки и добавляешь в интерфейс метод, то раньше у тебя все пользователи, реализующие интерфейс, ломались; и им нужно было определить у себя добавленный метод.
Это в джамшутской терминологии "ломались". В нормальной: "все наследники получали корректирующую ошибку о недореализованном методе".
Q>С добавлением default interface methods — нет, больше не ломаются, и явно реализовывать новый API им не требуется.
Спасибо, б%%%! Мало нам таймбомб — давайте теперь ещё и эти.
Q>Если по умолчанию разрешать вызов без приведения, то добавление нового метода Method() сломает компиляцию, то есть defeats the whole idea.
Не надо про УСЛОВНЫЕ СЛУЧАИ. Есть процесс разработки. Если у тебя есть библиотека и она обновилась, там всегда есть breaking changes. Хочешь — не обновляйся и ничего дореализовывать не надо. Хочешь свежачок — компильни, проверь ошибки, дореализуй контракт. Всё. Просто как день. Здесь не идёт вопрос об обратной совместимости — это эволюция продукта, где допустимо улучшение, требующее правки чужих исходников.
Здравствуйте, Codealot, Вы писали:
C> obj.Method(); // error C>Вот за каким хреном так сделали?
Я с большим подозрением стал относиться к "фичам" C# после версии 8.0; Такое ощущение, что все адекваты махнули рукой и сказали "А, лепите что хотите, я устал спорить!".
Только так можно объяснить поток ОЧЕВИДНО СПОРНЫХ фич, которые обсуждаются хрен знает кем, одабриваются ещё более странными персонами и выкатываются в релиз без широкого обсуждения на общедоступных сайтах. (почему не LJ? Facebook? StackOverflow? Да потому что ТАМ НЕЛЬЗЯ ЗАТКНУТЬ РОТ ОППОНЕНТАМ! )
Унылые, обидчивые посредственности выкатывают очередной высер их банального мозга (или того хуже — плохо понятые фичи других языков) и начинается шапкозакидательство тех, кто смеет этих посредственностей критиковать. Более того — количество критики вообще никак не влияет на последущее решение — фича просто делается по задумке тупого индуса-придумщика и далее преподносится как очередной "прорыв". Я видел кучи обсуждений на мелкомягком междусобойчике в github и ты никогда не доведёшь свою мысль до их замкнутого разума.
Вот почему Nemerle — наше всё. Всегда можно общедоступно обсудить спорные моменты и более того — даже самому реализовать так, как ты считаешь нужным! Да, бывают в жизни и "две правды" сразу, но никто не имеет права принуждать тебя использовать "чужую" правду. У кого какие задачи — тот пусть себе и пилит "наименее спорный вариант" фичи.
Вот дефолтовые методы в интерфейсах — я думал, это что-то полезное! Оказалось, высер.