Источник: FreeCodeCamp
Java — один из самых популярных объектно-ориентированных языков программирования, используемых сегодня. Поскольку он не зависит от платформы, вы можете найти Java-приложения на всех типах устройств и в каждой операционной системе. А поскольку Java относительно легко выучить, это один из языков, который осваивают многие программисты.
Важная особенность Java, с которой вы должны быть знакомы, — это наследование классов. Наследование позволяет оптимизировать код, облегчая повторное использование классов. Когда вы можете повторно использовать код, который уже был протестирован и отлажен, жизненный цикл разработки программного обеспечения становится короче и менее затратным.
Хотя теоретически это простая концепция, кодирование отношений наследования требует внимания к деталям. Особенно в отношении множественного наследования, когда один дочерний класс наследует свойства от нескольких родительских классов.
Java отвергает множественные отношения наследования, потому что они создают неоднозначность, но есть несколько способов добиться многих из тех же эффектов, если вы знаете, что делать.
В этой статье мы рассмотрим проблемы с множественным наследованием и обсудим альтернативные варианты кодирования на Java.
Терминология наследования
Иногда, чтобы стать успешным программистом, вам нужно научиться решать проблемы, чтобы найти обходные пути для общих ошибок или проблем. Это необходимая часть безопасного и умного кодирования. Одна из таких проблем связана с множественным наследованием (точнее, его отсутствием) в Java. Чтобы полностью понять наследование в Java, вам необходимо ознакомиться с базовой терминологией наследования объектно-ориентированного программирования (ООП).- Классы — это фундаментальная структура шаблона в объектно-ориентированных языках программирования. Класс определяет общие свойства для группы объектов.
- Родительский класс: также известный как базовые классы или суперклассы. Родительский класс — это расширяемый класс, который предоставляет функции дочернему классу. Он допускает возможность повторного использования. Определения и функции родительского класса повторно используются при создании дочерних классов.
- Дочерний класс: более обобщенно называемый подклассом, дочерний класс наследует функции от другого класса. Дочерние классы — это расширенные или производные классы.
- Наследование: отношения между родительским и дочерним классами.
Типы наследования ООП
Сегодня используется множество популярных объектно-ориентированных языков программирования, включая Java, C ++ , JavaScript, Python, PHP, Ruby и Perl. Хотя наследование является общей концепцией для этих языков ООП, не все типы наследования существуют в каждом из этих языков. Крайне важно знать общие типы наследования и ограничения на наследование на конкретном языке, который вы используете. Чем больше вы знаете о наследовании, тем более эффективным разработчиком вы станете. Типы наследования, поддерживаемые Java, включают:- Одноуровневое наследование: когда дочерний класс наследует функции от единственного родительского класса.
- Многоуровневое наследование: это многоуровневая форма одноуровневого наследования. При многоуровневом наследовании дочерний класс также может выступать в качестве родительского класса для других дочерних классов. Отношения между каждым уровнем линейны — никакие ветви не выходят выше, чем при множественном наследовании. В этом случае конечный дочерний класс имеет функции со всех уровней выше.
- Иерархическое наследование: противоположность множественного наследования. В иерархическом наследовании единственный родительский класс имеет более одного дочернего класса. Таким образом, вместо того, чтобы иметь ветви над ним, он разветвляется внизу.
- Гибридное наследование: как следует из названия, гибридное наследование представляет собой комбинацию других типов наследования.
- Множественное наследование: при множественном наследовании дочерний класс имеет более одного родительского класса. Хотя Java и JavaScript не поддерживают множественное наследование, такие языки ООП, как C ++, поддерживают.
- Многопутевое наследование: гибрид множественного, многоуровневого и иерархического наследования, при многопутевом наследовании дочерний класс наследует свои характеристики и функции от родительского класса и нескольких дочерних классов родительского класса. Поскольку многопутевое наследование основано на множественном наследовании, Java не поддерживает его использование.
Почему Java не поддерживает множественное наследование
Основная проблема множественного наследования заключается в том, что оно может создавать неоднозначности в дочерних классах. В обзорном техническом документе 1995 года ведущий дизайнер Java Джеймс Гослинг заявил, что проблемы с множественным наследованием были одной из причин создания Java. Сложности, присущие множественному наследованию, наиболее отчетливо видны в проблеме алмаза. В задаче “ромб” родительский класс A имеет два различных дочерних класса B и C; то есть дочерние классы B и C расширяют класс A. Теперь мы создаем новый дочерний класс D, который расширяет как класс B, так и класс C. Обратите внимание, что у нас есть множественное наследование (D расширяет B и C), иерархическое наследование (B и C расширяют A) и многоуровневое наследование (D расширяет A, B и C). В проблеме ромба дочерние классы B и C наследуют метод от родительского класса A. И B, и C переопределяют унаследованный метод. Но новые методы в B и C противоречат друг другу. Окончательный дочерний класс D наследует два независимых и конфликтующих метода от своих нескольких родителей B и C. Неясно, какой метод класса D следует использовать, поэтому возникает двусмысленность. Другие языки программирования ООП реализуют различные методы решения неоднозначности множественного наследования.Как решить проблему множественного наследования в Java
То, что множественное наследование проблематично, не означает, что оно бесполезно. Есть много ситуаций, когда вы можете захотеть, чтобы один класс имел функции из нескольких других классов. Только подумайте об автомобиле Tesla Roadster, который вы купите, когда станете чрезвычайно успешным разработчиком программного обеспечения. Его технические характеристики основаны как на классе спортивных автомобилей, так и на классе электромобилей. Еще один пример: браузер, через который вы читаете эту статью. В нем есть функции из класса решений для обеспечения конфиденциальности данных в интернете и из общего класса интернет-браузеров. Но вы не можете расширить несколько классов в Java. Так как же этот язык справляется с проблемой множественного наследования? Java использует структуры, называемые интерфейсами. Интерфейсы — это абстрактные типы, которые определяют поведение для реализации классами. Поскольку они абстрактны, интерфейсы не содержат подробных инструкций по их поведению. Вместо этого классы предоставляют конкретные реализации поведения интерфейса. Интерфейсы имеют несколько определяющих характеристик:- В отличие от классов, вы не создаете экземпляры интерфейсов. Вместо этого классы реализуют интерфейсы.
- Интерфейсы содержат только общедоступные определения констант и заголовки методов.
- Интерфейсы могут расширять только другие интерфейсы, но не классы.
- Интерфейсы могут расширять несколько интерфейсов, а классы могут реализовывать несколько интерфейсов.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ