Pull to refresh

Comments 23

Это не модификаторы доступа что-то тормозят, это плохо построенная программа обучения тормозит.

Ни в С++, ни в Python ни во множестве других языков программирования интерфейсов нет. Почему, см, например один из ответов на вопрос How do you declare an interface in C++? на stackoverflow.com:

The whole reason you have a special Interface type-category in addition to abstract base classes in C#/Java is because C#/Java do not support multiple inheritance.


Т.е, может быть надо учить новичков ООП, используя «нормальные» языки?
По крайней мере в нем есть множественное наследование…

И эта одна из вещей, которая делает его ненормальным :)

Дерево — это частный случай направленного графа без циклов. Опять же, не нужно — никто не заставляет использовать. Что тут ненормального?
Забивать можно и шурупы отверткой, но мы же хотим писать хороший код? Множественное наследование обычно используется как наследование реализации, а это НЕ правильный способ использовать ООП. Чтобы избежать дублирования кода нужно использовать композицию, а не наследование. А множественное наследование примененое к месту почти наверняка подразумевает по смыслу множественные интерфейсы.

Таким образом у языков выбравших интерфейсы есть два преимущества. Во-первых они затрудняют неверное применение ООП, а во-вторых они позволяют программисту явно выразить знание о том какой тип является интерфейсом, а какой — реализацией.

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

Да, только при этом никакого противопоставления этого подхода и использования модификаторов доступа ведь не происходит?

А его и в случае с интерфейсами не происходит: просто у них (по крайней мере, в C#) неявный модификатор public, вот и все. Я это противопоставление изначально считаю ошибочным.

Судя про приведенной в статье табличке, это не так.

Единственная виденная мной в тексте табличка не имеет никакого отношения к интерфейсам в C#.

Опс. Не понимаю, почему внимательно не прочитал подпись к этой таблице.
Я не знаю что автор хотел сказать этой табличкой, но в Java все методы интерфейсов тоже публичны (так же как в C#).
Java Language Specification 6.6.1:
All members of interfaces are implicitly public.
Более того я затрудняюсь представить себе язык где это не так.
к сожалению вы дали слишком старую ссылку

начиная с 9й java
openjdk.java.net/jeps/213

It is also proposed that interfaces be allowed to have private methods.

всё началось с момента как в интерфейсы довезли default методы которые предоставляют реализацию, а потом пошло поехало…

www.journaldev.com/12850/java-9-private-methods-interfaces

теперь ответить на вопрос на собесе «чем отличается абстрактный класс от интерфейса» стало ещё сложнее =)

с шарпом тоже не всё так однозначно

docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#default-interface-methods

дефолт методы туда подвезли и там же:
Any of the modifiers are allowed on interface members.

то есть ожидаем static, private и тд
Ваша правда — отстал от жизни. Я то просто всё еще на Java 8 / Kotlin сижу.
The whole reason you have a special Interface type-category in addition to abstract base classes in C#/Java is because C#/Java do not support multiple inheritance.
Я бы сказал все с точностью до наоборот. В современных языках намеренно не делают множественное наследование, потому что это создает проблемы и на уровне языка и на уровне кода. А интерфейсы это наоборот элементы идиоматического ООП, позволяющие писать красивый код со статическими проверками. Извращаются над ООП плюсы, а не шарп с джавой.
Есть техническая проблема. Есть техническое решение. Если кто-то не может осилить как пользоваться инструментом и\или понять, для решения каких проблем предназначен инструмент — может не стоит «ругать» инструмент? Это не техническая проблема, а административная.

Один нюанс — интерфейс это декларация контракта взаимодействия с внешним миром. Тогда надо «приделать» как-то декларацию границ «внешнего мира» для которых этот интерфейс действителен и следить за соблюдением.
Чем это отличается от public\protected\private? Как по мне, так просто изменили место где просиходит такая декларация.
То что изобрен еще один велосипед — так иногда бывает.

Вообще идея на ограничение доступа через интерфейсы имеет право на жизнь. Например встречающиеся часто задачи типа сериализации, гидрации, тестирования и т. п., которые требуют от внешних объектов доступа ко всем или почти всем потрохами "подопытного" объекта. И появляется дилемма: ели делать потроха публичными, или использовать (дорогую) рефлексию. Если в обычных клиентах класса User использовать его только как публичный интерфейс IUser, то попытки залезть в потроха через что-то вроде if user instanceof User, чтобы получить доступ к "приватным" методам будут легко замечены на код ревью

Всё проще и обходится без подмены понятий.
Нельзя использовать класс за пределами библиотеки, его реализующей. Снаружи только интерфейсы. Да и внутри кроме объявления упоминаться должен только в билдерах, а лучше вообще только в IoC/DI контейнере.
А для тестирования отлично проблему решает особая конфигурации оного контейнера.

Это даже не ересь, а просто глупость какая-то. Модификаторы доступа — это одно, инкапсуляция — это другое, а интерфейсы и вовсе третье.
Пытаясь одно заменить другим при обучении, мы получите ещё одного неадекватного программиста, творческие порывы которого будут душить на код-ревью.
При инкапсуляции под капотом объекта может быть всё, что угодно: поля, методы, другие объекты и интерфейсы; и прикрывать это надо, чтобы оно работало так, как хочет объект.
Интерфейс — суть контракт, хороший инструмент изоляции и даже полиморфизма. Пофиг, что его реализует, главное, чтобы соответствовало спецификации. Но делать им инкапсуляцию — примерно то же, что закручивать шурупы пассатижами.

Sign up to leave a comment.

Articles