Я недавно начал смотреть на разработку Android. Это вернуло меня в мир разработки программного обеспечения на Java. В прошлый раз, когда я работал с Java, я должен признать, что ООП я не понимал почти так же, как (я думаю), что я делаю сейчас.
Поскольку я в основном использовал C # в своей карьере, я заметил поразительную разницу в том, как наследуется Java и C #.
В C # казалось, что наследования можно избежать в большинстве ситуаций. Поставленная задача обычно может быть решена с помощью конкретных классов .NET Framework.
В Java, из того, что я собираю из примеров кода, похоже, что среда Java предоставляет множество интерфейсов или абстрактных классов, которые затем должны быть реализованы / расширены разработчиком.
Это кажется слишком большой разницей, чтобы просто сводиться к стилю. В чем причина этого? Я чувствую, что не буду писать чистый Java-код, пока не пойму этого.
Кроме того, это ограничено только Android SDK или это обще-Java подход к ООП?
Или поставить по-другому,
Что в дизайне этих двух языков (кажется, поощряет) более или менее наследственное использование, чем в другом?
Если языки относятся к наследованию одинаково, и если предположить, что мои наблюдения верны, то это означает, что это связано с дизайном фреймворков / библиотек, а не с языками. Какова будет мотивация для такого дизайна?
источник
Ответы:
Я понимаю, что это в значительной степени является просто стилевое решение. Ну, возможно, не стиль, а идиомы языка / среды. Разработчики стандартной библиотеки Java следовали одному набору рекомендаций по проектированию, а разработчики .NET - другому (хотя у них была возможность увидеть, как работает подход Java).
В реальных языках очень мало, чтобы поощрять или отговаривать наследование. Только две вещи кажутся мне актуальными:
.NET представили дженерики раньше, еще до того, как было реализовано слишком много неуниверсального кода. Альтернатива - много наследования, чтобы типизировать специализированные вещи.
Большим изменением было то, что .NET поддерживал делегатов. В Java вы застряли с (анонимным) наследованием, чтобы обеспечить базовую функциональность переменных. Это приводит к относительно большой разнице в том, как код разработан, чтобы либо использовать преимущества делегатов, либо избегать неуклюжих структур наследования, необходимых для этого в Java.
источник
Это очень разные языки, особенно в этой области. Допустим, у вас есть класс. В этом случае мы сделаем это пользовательским элементом управления, что-то вроде текстового поля. Назовите это UIControl. Теперь мы хотим поместить это в другой класс. В этом случае, поскольку мы используем пользовательский интерфейс для нашего примера, мы назовем его классом CleverPanel. Наш экземпляр CleverPanel захочет узнать о том, что происходит с его экземпляром UIControl по разным причинам. Как это сделать?
В C # основной подход заключается в проверке различных событий, настройке методов, которые будут выполняться при запуске каждого интересного события. В Java, в которой отсутствуют события, обычным решением является передача объекта с различными методами обработки «события» в метод UIControl:
Пока что разница между C # и Java невелика. Однако у нас есть интерфейс DoSomething, который не нужен в C #. Кроме того, этот интерфейс может включать в себя множество методов, которые не нужны большую часть времени. В C # мы просто не обрабатываем это событие. В Java мы создаем класс, который обеспечивает нулевую реализацию для всех методов интерфейса, DoSomethingAdapter. Теперь мы заменяем DoSomething на DoSomethingAdapter, и нам вообще не нужно писать никаких методов для чистой компиляции. В итоге мы просто переопределяем методы, необходимые для правильной работы программы. Таким образом, в итоге нам нужен интерфейс и использование наследования в Java, чтобы соответствовать тому, что мы делали с событиями в C #.
Это пример, а не всестороннее обсуждение, но он дает основы того, почему в Java так много наследования, в отличие от C #.
Теперь, почему Java работает таким образом? Гибкость. Объект, переданный на whenSomethingHappens, мог быть полностью передан CleverPanel из другого места. Это может быть что-то, что несколько экземпляров CleverPanel должны передать своим UIControl-подобным объектам, чтобы помочь объекту CleverWindow где-нибудь. Или UIControl может передать его одному из своих компонентов.
Кроме того, вместо адаптера может быть где-то реализация DoSomething, за которой стоят тысячи строк кода. Мы могли бы создать новый экземпляр этого и передать его. Возможно, нам придется переопределить один метод. Обычная хитрость в Java - иметь большой класс с таким методом:
Затем в CleverlPanel:
Платформа Java с открытым исходным кодом делает многое из этого, что побуждает программистов делать больше - и потому, что они следуют этому в качестве примера, и просто для того, чтобы использовать его. Я действительно думаю, что базовый дизайн языка лежит в основе разработки фреймворка Sun и позади использования Java-программистом техник, когда фреймворк не используется.
Создать класс на лету очень просто. На класс, анонимный или именованный, нужно ссылаться только в одном небольшом блоке кода, скрытом глубоко в одном методе. Он может быть создан совершенно новым или путем небольших модификаций очень большого существующего класса. (И существующий класс может быть верхнего уровня в своем собственном файле, или вложенным в класс верхнего уровня, или определяться только в пределах одного блока кода). Новый экземпляр класса может иметь полный доступ ко всем данным создаваемого объекта. И новый экземпляр можно передать и использовать по всей программе, представляя объект, который его создал.
(Кроме того, обратите внимание, что широкое использование наследования здесь - как и в других местах в Java - просто для целей СУХОЙ. Это позволяет различным классам повторно использовать один и тот же код. Обратите внимание также на простоту наследования в Java, которая поощряет это. )
Опять же, это не всестороннее обсуждение; Я просто царапаю поверхность здесь. Но да, есть удивительная разница в том, как наследование используется между Java и C #. В этом отношении они очень разные языки. Это не ваше воображение.
источник
Нет абсолютно никакой разницы в способах наследования между Java и C #. Когда вы на самом деле будете использовать наследование или композицию, это определенно дизайнерское решение, и ни в коем случае это не то, что Java или C # поощряет или не поощряет. Я хотел бы предложить прочитать эту статью .
Надеюсь, я помог!
источник