Что такое суперкласс Java

Учебник по наследованию Java: объясняется на примерах

Наследование – это процесс создания нового класса на основе функций другого существующего класса. I… С пометкой java, учебник, ооп.

  • Автор записи

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

Однако каждый язык имеет свой собственный уникальный способ реализации наследования, который может затруднить переключение.

Сегодня мы проведем ускоренный курс по использованию наследования в программировании на Java и покажем вам, как реализовать основные инструменты наследования, такие как приведение типов, переопределение методов и окончательные сущности.

Вот что мы рассмотрим сегодня:

  • Что такое наследование?
  • Наследование в Java
  • Примеры наследования Java
  • Продвинутые концепции для изучения следующий
Внедряйте Java в два раза быстрее

Получите практическую практику с нашим лучшим контентом Java, адаптированным к текущему уровню квалификации разработчиков.

Java для программистов

Что такое наследование?

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

Наследование имеет важное значение для продвинутого Объектно-ориентированное программирование (ООП), поскольку оно позволяет повторно использовать функции одного класса в вашей программе без репликации кода.

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

Например, вы могли бы создать класс Автомобиль который указывает колеса и подкласс Седан , который включает в себя атрибут двери . Поток отношений наследования часто отражает логические отношения, аналогичные квадратам и прямоугольникам; в этом случае все седаны являются автомобилями, но не все автомобили являются седанами.

Наследование имеет три основных преимущества:

  1. Возможность повторного использования: Наследование позволяет повторно использовать функции существующего класса неограниченное количество раз в любом классе, который наследует этот класс. Вы можете сохранить согласованную функциональность для всех объектов одного типа, не переписывая код.
  2. Структура кода: Наследование обеспечивает четкую, понятную логическую структуру для вашей программы. Это позволяет разработчикам понимать ваш код как набор связанных, но уникальных категорий, а не просто как блок кода.
  3. Скрытие данных: Базовый класс может быть настроен на сохранение некоторых данных в тайне, чтобы они не могли быть изменены производным классом. Это пример инкапсуляции, когда доступ к данным ограничен только теми классами, которые нуждаются в них для своей роли.

Наследование в Java

Каждый язык программирования имеет несколько иную терминологию для наследования. В Java родительский класс называется суперклассом , а класс-наследник называется подклассом . Разработчики могут также называть суперклассы базовыми или родительскими классами, а подклассы производными или дочерними классами.

Подклассы связаны с суперклассами с помощью ключевого слова extends при их определении. Подклассы могут определять новые локальные методы или поля для использования или могут использовать ключевое слово super для вызова унаследованных методов или суперконструктора.

Когда использовать супер ключевое слово

супер – это, по сути, кнопка “предыдущее значение”, вызываемая из дочернего класса, которая позволяет вам читать и получать доступ к функциям родительского класса независимо от их значения в текущем дочернем классе.

Ключевое слово супер используется для:

  • Доступ к полям родительского класса : super.var считывает значение var , заданное в родительском классе, в то время как var самостоятельно считывает измененное значение из дочернего класса.
  • Вызов метода родительского класса : super.method() позволяет дочернему классу получить доступ к реализации родительского класса method() . Это требуется только в том случае, если дочерний класс также имеет метод с тем же именем.
  • Использование конструкторов : Это позволяет создавать новые экземпляры родительского класса из дочернего класса.

Напомним, что конструкторы в Java – это специальные методы, используемые для инициализации объектов. Вызов суперконструктора создает новый объект, для которого требуются все поля, определенные в конструкторе родительского класса.

Затем вы можете добавить дополнительные поля в другие инструкции, чтобы сделать дочерний экземпляр более конкретным, чем родительский. По сути, это позволяет вам использовать конструктор родительского класса в качестве шаблона для конструктора дочернего класса.

Типы наследования

В Java доступно несколько типов наследования:

Одиночное наследование – это когда один подкласс наследуется от суперкласса, образуя один уровень наследования.

Многоуровневое наследование – это когда суперкласс наследуется промежуточным классом, который затем наследуется производным классом, образуя 3 или более уровней наследования.

Иерархическое наследование – это когда один суперкласс служит основой для нескольких конкретных подклассов. Это наиболее распространенная форма наследования.

Существуют также два других типа наследования, которые доступны только в Java благодаря сочетанию наследования классов и интерфейсов.

Множественное наследование , когда один подкласс наследуется от нескольких родительских классов.

Гибридное наследование , смесь двух или более из вышеперечисленных видов наследования.

Java не поддерживает множественное наследование с классами, что означает, что оба этих типа наследования невозможны только с классами Java. Однако подкласс может наследовать более одного интерфейса (абстрактный класс). Таким образом, вы можете имитировать множественное наследование, если вы объедините использование интерфейсов и классов.

Примеры наследования Java

Чтобы помочь вам лучше понять наследование, давайте перейдем к некоторым примерам кода. Обратите внимание на синтаксические компоненты наследования, которые мы видели до сих пор, такие как супер и общие методы.

Чтобы объявить наследование в Java, мы просто добавляем extends [суперкласс] после идентификатора подклассов.

Вот пример класса Car , который наследуется от базового класса Vehicle с использованием частных строк и методов получения/установки для достижения инкапсуляции.

Это пример одинарного наследования, так как только один объект наследуется от родительского класса. В строке 37 вы можете видеть , что мы используем super для вызова конструктора суперкласса , который упрощает наш конструктор Car . Вы также можете увидеть, как Автомобиль имеет доступ к классу транспортного средства методу printDetails() в строке 42 .

печать сведений() может быть вызвана без супер потому что Автомобиль не имеет собственной реализации печать деталей() . Ключевое слово супер необходимо только тогда, когда программа должна решить, какая версия метода используется.

Приведение типов в Java

Java также позволяет ссылаться на подкласс как на экземпляр его суперкласса, по сути, рассматривая подкласс так, как если бы он принадлежал к типу суперкласса. Этот процесс известен как приведение типов . Это отличный способ создания модульного кода, так как вы можете написать код, который будет работать для любого подкласса одного и того же родителя. Например, вы можете ссылаться на переменную типа Автомобиль как на объект типа Транспортное средство .

Сначала мы создаем экземпляр Car , а затем присваиваем этот экземпляр переменной типа Vehicle . Теперь ссылка на переменную Vehicle указывает на экземпляр Car . Это позволяет вам обрабатывать любой подкласс Транспортного средства как то же самое Транспортное средство тип, даже если вы не знаете к какому подклассу Транспортного средства он относится. Существует два типа типизации: восходящая и нисходящая.

Повышение – это когда вы обращаетесь с дочерним классом так, как если бы он был экземпляром родительского класса, как в нашем предыдущем примере. Любые поля, уникальные для дочернего класса, будут скрыты, чтобы они соответствовали форме родительского класса.

Понижение – это когда вы обращаетесь с экземпляром родительского класса так, как если бы он был одним из его дочерних классов. В то время как любой подкласс может быть повышен, только объекты, которые изначально были типизированы для подкласса, могут быть понижены.

Другими словами, объект может быть понижен, если объект изначально принадлежал к типу подкласса, но позже был повышен до родительского класса.

Переданный объект по-прежнему сохраняет поля, которые у него были, и поэтому может быть добавлен обратно, чтобы снова сделать его допустимым объектом типа дочернего класса.

Однако объекты, которые изначально принадлежали родительскому классу, не имеют значений для каких-либо существенных полей, уникальных для дочернего класса. В результате он будет компилироваться, но выдаст ошибку во время выполнения.

Переопределение методов в Java

Иногда нам понадобится один из наших подклассов, чтобы изменить поведение унаследованного метода. Java позволяет нам делать это, переопределяя существующие методы путем создания новых методов с тем же именем. Это также позволяет нам предоставлять классовые реализации абстрактных методов из интерфейсов.

Переопределение методов является фундаментальным инструментом при реализации полиморфизма, принципа проектирования, который позволяет разным классам иметь уникальные реализации для одного и того же метода. Если мы разберем это слово, то “поли” означает “много”, а “морф” означает “форма”.

Проще говоря, полиморфизм означает наличие множества специфичных для класса форм процесса для выполнения одной и той же задачи.

Вот функции, которыми должна обладать программа, чтобы разрешить переопределение методов:

  • Переопределение метода требует наследования, и должен быть хотя бы один производный класс.
  • Производные классы должны иметь такое же объявление, т.е. модификатор доступа, имя, те же параметры и тот же тип возвращаемого метода, что и у базового класса.
  • Метод в производном классе или классах должен иметь реализацию, отличную друг от друга.
  • Метод в базовом классе должен быть переопределен в производном классе.
  • Базовый класс/метод не должен быть объявлен как Конечный класс. Чтобы переопределить метод в Java, определите новый метод с тем же именем, что и метод, который вы хотите переопределить, и добавьте @Переопределить тег над ним.

Здесь вы можете увидеть пример того, как мы можем создать поведение, зависящее от класса, для одного и того же вызова метода. Наш вызов метода всегда get Area() однако реализация метода зависит от класса оцениваемой фигуры.

Преимущества переопределения методов заключаются в следующем:

  • Каждый производный класс может предоставлять свои собственные конкретные реализации унаследованным методам, не изменяя методы родительского класса.
  • Для любого метода дочерний класс может использовать реализацию в родительском классе или создать свою собственную реализацию. Этот вариант обеспечивает вам большую гибкость при разработке решений.

Последнее ключевое слово

В Java ключевое слово final может использоваться при объявлении переменной, класса или метода, чтобы сделать значение неизменным. Значение сущности определяется при инициализации и будет оставаться неизменным на протяжении всей программы. Попытка изменить значение чего-либо, объявленного как final , приведет к ошибке компилятора.

Точное поведение final зависит от типа сущности:

  • финал Параметр не может быть изменен нигде в функции
  • окончательный Метод не может быть переопределен или скрыт каким-либо подклассом
  • окончательный Класс не может быть родительским классом для любого подкласса

Хотя значение сущностей final изменить нельзя, их можно использовать для установки значений переменных, не относящихся к final . Это свойство делает его полезным для решения проблем изменчивости данных, когда для функционирования нескольких разделов кода необходимо ссылаться на один и тот же объект.

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

Продвинутые концепции для изучения следующий

Наследование является мощным инструментом в Java и имеет важное значение для понимания передовых конструкций ООП. Некоторые следующие концепции, которые следует изучить на вашем пути разработки Java, следующие:

  • Абстракция и интерфейсы
  • Агрегация
  • Композиция
  • Расширенные модификаторы доступа

Чтобы помочь вам понять эти и другие передовые концепции, мы создали Java для разработчиков Путь . Внутри вы найдете коллекцию нашего лучшего контента на Java по таким темам, как ООП, многопоточность, рекурсия и новые функции Java 8. Эти уроки выбраны из всей нашей библиотеки курсов, что позволяет вам учиться на наших лучших материалах для каждой концепции.

К концу у вас будут навыки и практический опыт, необходимые для успешного прохождения следующего собеседования на Java.

Наследование

Наследование является неотъемлемой частью Java. При использовании наследования вы говорите: Этот новый класс похож на тот старый класс. В коде это пишется как extends, после которого указываете имя базового класса. Тем самым вы получаете доступ ко всем полям и методам базового класса. Используя наследование, можно создать общий класс, которые определяет характеристики, общие для набора связанных элементов. Затем вы можете наследоваться от него и создать новый класс, который будет иметь свои уникальные характеристики. Главный наследуемый класс в Java называют суперклассом. Наследующий класс называют подклассом. Получается, что подкласс — это специализированная версия суперкласса, которая наследует все члены суперкласса и добавляет свои собственные уникальные элементы. К примеру, в Android есть класс View и подкласс TextView.

Чтобы наследовать класс, достаточно вставить имя наследуемого класса с использованием ключевого слова extends:

В этом коде мы наследуемся от класса Activity и добавляем свой код, который будет отвечать за наше приложение.

Подкласс в свою очередь может быть суперклассом другого подкласса. Так например, упоминавший ранее класс TextView является суперклассом для EditText.

В производный класс можно добавлять новые методы.

Для каждого создаваемого подкласса можно указывать только один суперкласс. При этом никакой класс не может быть собственным суперклассом.

Хотя подкласс включает в себя все члены своего суперкласса, он не может получить доступ к тем членам суперкласса, которые объявлены как private.

Помните, мы создавали класс Box для коробки кота. Давайте наследуемся от этого класса и создадим новый класс, который будет иметь не только размеры коробки, но и вес.

В том же файле Box.java после последней закрывающей скобки добавьте новый код:

Возвращаемся в главную активность и пишем код:

Обратите внимание, что мы вызываем метод getVolume(), который не прописывали в классе HeavyBox. Однако мы можем его использовать, так как мы наследовались от класса Box и нам доступны все открытые поля и методы. Заодно мы вычисляем вес коробки с помощью новой переменной, которую добавили в подкласс.

Теперь у нас появилась возможность складывать в коробку различные вещи. В хозяйстве всё пригодится.

При желании вы можете создать множество разных классов на основе одного суперкласса. Например, мы можем создать цветную коробку.

Ключевое слово super

В Java существует ключевое слово super, которое обозначает суперкласс, т.е. класс, производным от которого является текущий класс. В данном случае, супер не означает превосходство, скорее даже наоборот, дочерний класс имеет больше методов, чем родительский. Само слово пошло из теории множеств, где используется термин супермножество. Посмотрим, зачем это нужно.

В конструкторе HeavyBox мы дублировали поля width,height и depth, которые уже есть в классе Box. Это не слишком эффективно. Кроме того, возможны ситуации, когда суперкласс имеет закрытые члены данных, но мы хотим иметь к ним доступ. Через наследование это не получится, так как закрытые члены класса доступны только родному классу. В таких случаях вы можете сослаться на суперкласс.

Ключевое слово super можно использовать для вызова конструктора суперкласса и для обращения к члену суперкласса, скрытому членом подкласса.

Использование ключевого слова super для вызова конструктора суперкласса

Вызов метода super() всегда должен быть первым оператором, выполняемым внутри конструктора подкласса.

При вызове метода super() с нужными аргументами, мы фактически вызываем конструктор Box, который инициализирует переменные width, height и depth, используя переданные ему значения соответствующих параметров. Вам остаётся инициализировать только своё добавленное значение weight. При необходимости вы можете сделать теперь переменные класса Box закрытыми. Проставьте у полей класса Box модификатор private и убедитесь, что вы можете обращаться к ним без проблем.

У суперкласса могут быть несколько перегруженных версий конструкторов, поэтому можно вызывать метод super() с разными параметрами. Программа выполнит тот конструктор, который соответствует указанным аргументам.

Вторая форма ключевого слова super действует подобно ключевому слову this, только при этом мы всегда ссылаемся на суперкласс подкласса, в котором она использована. Общая форма имеет следующий вид:

Здесь член может быть методом либо переменной экземпляра.

Подобная форма подходит в тех случаях, когда имена членов подкласса скрывают члены суперкласса с такими же именами.

В результате мы должны увидеть:

Таким образом, знакомое нам выражение super.onCreate(savedInstanceState) обращается к методу onCreate() из базового класса.

Создание многоуровневой иерархии

Мы использовали простые примеры, состоящие из суперкласса и подкласса. Можно строить более сложные конструкции, содержащие любое количество уровней наследования. Например, класс C может быть подклассом класса B, который в свою очередь является подклассом класса A. В подобных ситуациях каждый подкласс наследует все характеристики всех его суперклассов.

Напишем пример из трёх классов. Суперкласс Box, подкласс HeavyBox и подкласс MoneyBox. Последний класс наследует все характеристики классов Box и HeavyBox, а также добавляет поле cost, которое содержит стоимость коробки.

Box.java

HeavyBox.java

MoneyBox

Код для основной активности, например, при щелчке кнопки:

В результате мы получим различные значения, вычисляемые в коде. Благодаря наследованию, класс MoneyBox может использовать классы Box и HeavyBox, добавляя только ту информацию, которая нам требуется для его собственного специализированного применения. В этом и состоит принцип наследования, позволяя повторно использовать код.

Метод super() всегда ссылается на конструктор ближайшего суперкласса в иерархии. Т.е. метод super() в классе MoneyBox вызывает конструктор класса HeavyBox, а метод super() в классе HeavyBox вызывает конструктор класса Box.

Если в иерархии классов конструктор суперкласса требует передачи ему параметров, все подклассы должны передавать эти параметры по эстафете.

В иерархии классов конструкторы вызываются в порядке наследования, начиная с суперкласса и заканчивая подклассом. Если метод super() не применяется, программа использует конструктор каждого суперкласса, заданный по умолчанию или не содержащий параметров.

Вы можете создать три класса A, B, C, которые наследуются друг от друга (A←B←C), у которых в конструкторе выводится текст и вызвать в основном классе код:

Вы должные увидеть три строчки текста, определённые в каждом конструкторе класса. Поскольку суперкласс ничего не знает о своих подклассах, любая инициализация полностью независима и, возможно, обязательна для выполнения любой инициализацией, выполняемой подклассом.

Переопределение методов

Если в иерархии классов имя и сигнатура типа метода подкласса совпадает с атрибутами метода суперкласса, то метод подкласса переопределяет метод суперкласса. Когда переопределённый метод вызывается из своего подкласса, он всегда будет ссылаться на версию этого метода, определённую подклассом. А версия метода из суперкласса будет скрыта.

Если нужно получить доступ к версии переопределённого метода, определённого в суперклассе, то используйте ключевое слово super.

Не путайте переопределение с перегрузкой. Переопределение метода выполняется только в том случае, если имена и сигнатуры типов двух методов идентичны. В противном случае два метода являются просто перегруженными.

В Java SE5 появилась запись @Override; она не является ключевым словом. Если вы собираетесь переопределить метод, используйте @Override, и компилятор выдаст сообщение об ошибке, если вместо переопределения будет случайно выполнена перегрузка.

Для закрепления материала создадим класс Animal с одним методом.

Теперь создадим класс Cat, наследующий от первого класса.

Java знает, у родительского класса есть метод sleep(). Удостовериться можно следующим образом. Находясь в классе Cat, выберите в меню Source | Override/Implement Methods. . Появится диалоговое окно, где можно отметить флажком нужный метод.

Extends

В результате в класс будет добавлена заготовка:

Попробуем вызвать данный метод в основном классе активности:

Мы получим текст, который определён в суперклассе, хотя вызывали метод дочернего класса.

Но если мы хотим получить другой текст, совсем не обязательно придумывать новые методы. Достаточно закомментировать вызов метода из суперкласса и добавить свой вариант.

Запускаем программу и нажимаем на кнопку. И получим уже другой ответ, более соответствующий описанию среднестатистического кота. Заметьте, что код для щелчка кнопки мы не меняем, но система сама разберётся, что выводить нужно текст не из суперкласса, а из дочернего класса.

Рассмотрим другой пример переопределения методов. Создадим суперкласс Figure, который будет содержать размеры фигуры, а также метод для вычисления площади. А затем создадим два других класса Rectangle и Triangle, у которых мы переопределим данный метод.

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

Наследование

Наследование — это процесс перенимания классом свойств (методов и полей) другого класса. С использованием в Java наследования информация становится управляемой в иерархическом порядке.

Класс, который наследует свойства другого класса, называется подклассом (производным классом, наследующим классом), а класс, свойства которого наследуются, известен как суперкласс (базовый класс, родительский класс)

Ключевое слово extends

extends — это кодовое слово, используемое для наследования свойств класса. Взглянем на синтаксис этого ключевого слова.

Синтаксис

Пример кода

Дальше приведён пример процесса наследования на Java. На этом примере Вы можете рассмотреть два класса с именами Calculator и My_Calculator.

Используя ключевое слово extends в Java, My_Calculator перенимает методы addition() и subtraction() класса Calculator.

Скопируйте и вставьте эту программу в файле под именем My_Calculator.java

Скомпилируйте и выполните вышеприведённый код, как показано ниже.

После запуска программы получим следующий результат:

В данной программе, при создании объекта классу My_Calculator, копия содержимого суперкласса создаётся в нём же. Поэтому, используя объект подкласса, Вы можете получить доступ к членам суперкласса.

Наследование

Ссылочная переменная суперкласса может содержать объект подкласса, но, используя эту переменную, Вы можете иметь доступ только к членам суперкласса, поэтому, чтобы иметь доступ к членам обоих классов, рекомендуется всегда создавать ссылочную переменную к подклассу.

Обращаясь к программе выше, Вы можете создать экземпляр класса, как в примере ниже. Но, используя ссылочную переменную суперкласса, Вы не можете вызвать метод multiplication(), который принадлежит подклассу My_Calculator.

Примечание: подкласс наследует все члены (поля, методы, вложенные классы) из суперкласса. в Java конструкторы не являются членами, поэтому они не наследуются подклассом, но конструктор суперкласса может быть вызван из подкласса.

Ключевое слово super

Ключевое слово super схоже с ключевым словом this. Ниже приведены случаи, где используется super в Java.

  • Для дифференциации членов суперкласса от членов подкласса, если у них есть одинаковые имена.
  • Для вызова конструктора суперкласса из подкласса.

Дифференциация членов

Если класс перенимает свойства другого класса, и члены суперкласса имеют те же имена, что и в подклассе, для их разделения мы используем ключевое слово super, как показано ниже.

Пример кода

Этот раздел содержит программу, которая демонстрирует использование ключевого слова super в Java.

В предложенной программе у вас есть два класса с именами Sub_class и Super_class, оба имеющие метод display() с разными реализациями и переменную с именем num с разными значениями. Вы можете увидеть, что мы использовали ключевое слово super для дифференциации членов суперкласса из подкласса.

Скопируйте и вставьте эту программу в файле под именем Sub_class.java.

Скомпилируйте и выполните вышеприведённый код, как показано ниже.

После запуска программы будет получен следующий результат:

Вызов конструктора суперкласса

Если класс перенимает свойства другого класса, подкласс автоматически получается стандартный конструктор суперкласса. Но если Вы хотите вызвать параметризованный конструктор суперкласса, Вам нужно использовать ключевое слово super, как показано ниже.

Пример кода

В предложенной программе демонстрируется использование в Java ключевого слова super для вызова параметризованного конструктора. В этой программе содержится суперкласс и подкласс, где суперкласс содержит параметризованный конструктор, который принимает строковое значение, а мы используем ключевое слово super для вызова параметризованного конструктора суперкласса.

Скопируйте и вставьте эту программу в файле под именем Subclass.java

Скомпилируйте и выполните вышеприведённый код, как показано ниже.

После запуска программы будет выдан результат:

Отношение IS-A

IS-A — это способ сказать «Этот объект является типом этого объекта». Давайте посмотрим, как ключевое слово extends используется для достижения наследования.

Теперь, основываясь на примере выше, в объектно-ориентированных терминах, следующие утверждения верны

  • Animal является суперклассом класса Mammal.
  • Animal является суперклассом класса Reptile.
  • Mammal и Reptile являются подклассами класса Animal.
  • Dog одновременно является подклассом классов Mammal и Animal.

Теперь, используя отношение IS-A, мы можем сказать так:

  • Mammal IS-A Animal.
  • Reptile IS-A Animal.
  • Dog IS-A Mammal. Таким образом, Dog IS-A тоже Animal.

С использованием ключевого слова extend, подклассы могут наследовать все свойства суперкласса кроме его приватных свойств (private).

Мы можем убедиться, что Mammal на самом деле Animal с использованием оператора экземпляра.

Мы получим следующий результат:

Так как у нас есть хорошее понимание принципа работы ключевого слова extends, давайте рассмотрим, как используется ключевое слово implements для получения отношения IS-A.

В общем, ключевое слово implements в Java используется с классами для перенятия свойств интерфейса. Интерфейсы никогда не могут быть переняты классом с помощью extends.

Пример

Ключевое Слово instanceof

Давайте использует оператор instanceof в Java с целью проверки, являются ли Mammal и Dog на самом деле Animal.

Пример

Мы получим следующий результат:

Отношение HAS-A

Эти отношения в основном основаны на обращении. Они определяют, является ли определенный класс HAS-A определенным случаем. Эта взаимосвязь помогает уменьшить дублирование кода, а также баги. Взглянем на пример.

Мы видим, что у класса Van HAS-A (есть) Speed. Имея отдельный класс Speed, нам не нужно вставлять код, принадлежащий Speed в класс Van, что позволяет нам использовать класс Speed в нескольких приложениях.

В особенности объектно-ориентированного программирования, пользователям не нужно волноваться о том, какой объект выполняет текущую работу. Для достижения этого, класс Van скрывает детали реализации от пользователей класса Van. Таким образом, пользователи, должны попросить класс Van выполнить определенное действие, и класс Van либо выполнит работу сам по себе, либо попросит другой класс выполнить действие.

Виды наследования

Есть различные способы наследования, как показано ниже.

Вид Схема Пример
Одиночное наследование Наследование
Многоуровневое наследование Наследование
Иерархическое наследование Наследование
Множественное наследование Наследование

Очень важно запомнить, что Java не поддерживает множественное наследование. Это значит, что класс не может продлить более одного класса. Значит, следующее утверждение НЕВЕРНО:

Тем не менее, класс может реализовать один или несколько интерфейсов, что и помогло Java избавиться от невозможности множественного наследования.

Что такое суперкласс Java

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

И, возможно, впоследствии мы захотим добавить еще один класс, который описывает сотрудника предприятия — класс Employee. Так как этот класс реализует тот же функционал, что и класс Person, поскольку сотрудник — это также и человек, то было бы рационально сделать класс Employee производным (наследником, подклассом) от класса Person, который, в свою очередь, называется базовым классом, родителем или суперклассом:

Чтобы объявить один класс наследником от другого, надо использовать после имени класса-наследника ключевое слово extends , после которого идет имя базового класса. Для класса Employee базовым является Person, и поэтому класс Employee наследует все те же поля и методы, которые есть в классе Person.

Если в базовом классе определены конструкторы, то в конструкторе производного классы необходимо вызвать один из конструкторов базового класса с помощью ключевого слова super . Например, класс Person имеет конструктор, который принимает один параметр. Поэтому в классе Employee в конструкторе нужно вызвать конструктор класса Person. То есть вызов super(name) будет представлять вызов конструктора класса Person.

При вызове конструктора после слова super в скобках идет перечисление передаваемых аргументов. При этом вызов конструктора базового класса должен идти в самом начале в конструкторе производного класса. Таким образом, установка имени сотрудника делегируется конструктору базового класса.

Причем даже если производный класс никакой другой работы не производит в конструкторе, как в примере выше, все равно необходимо вызвать конструктор базового класса.

Производный класс имеет доступ ко всем методам и полям базового класса (даже если базовый класс находится в другом пакете) кроме тех, которые определены с модификатором private . При этом производный класс также может добавлять свои поля и методы:

В данном случае класс Employee добавляет поле company, которое хранит место работы сотрудника, а также метод work.

Переопределение методов

Производный класс может определять свои методы, а может переопределять методы, которые унаследованы от базового класса. Например, переопределим в классе Employee метод display:

Перед переопределяемым методом указывается аннотация @Override . Данная аннотация в принципе необязательна.

При переопределении метода он должен иметь уровень доступа не меньше, чем уровень доступа в базовом класса. Например, если в базовом классе метод имеет модификатор public, то и в производном классе метод должен иметь модификатор public.

Однако в данном случае мы видим, что часть метода display в Employee повторяет действия из метода display базового класса. Поэтому мы можем сократить класс Employee:

С помощью ключевого слова super мы также можем обратиться к реализации методов базового класса.

Запрет наследования

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

Если бы класс Person был бы определен таким образом, то следующий код был бы ошибочным и не сработал, так как мы тем самым запретили наследование:

Кроме запрета наследования можно также запретить переопределение отдельных методов. Например, в примере выше переопределен метод display() , запретим его переопределение:

В этом случае класс Employee не сможет переопределить метод display.

Динамическая диспетчеризация методов

Наследование и возможность переопределения методов открывают нам большие возможности. Прежде всего мы можем передать переменной суперкласса ссылку на объект подкласса:

Так как Employee наследуется от Person, то объект Employee является в то же время и объектом Person. Грубо говоря, любой работник предприятия одновременно является человеком.

Однако несмотря на то, что переменная представляет объект Person, виртуальная машина видит, что в реальности она указывает на объект Employee. Поэтому при вызове методов у этого объекта будет вызываться та версия метода, которая определена в классе Employee, а не в Person. Например:

Консольный вывод данной программы:

При вызове переопределенного метода виртуальная машина динамически находит и вызывает именно ту версию метода, которая определена в подклассе. Данный процесс еще называется dynamic method lookup или динамический поиск метода или динамическая диспетчеризация методов.

Наследование в Java: классов, методов и интерфейсов

Идея наследования в Java заключается в том, что вы можете создавать новые классы, основанные на существующих классах. Когда вы наследуете от существующего класса, вы можете повторно использовать методы и поля родительского класса. Более того, вы также можете добавлять новые методы и поля в ваш текущий класс.

Наследование представляет собой отношение IS-A, которое также известно как отношение родитель-ребенок.

Наследование в программировании на Java может быть определено как процесс, в котором один класс приобретает свойства (методы и поля) другого. С использованием наследования информация становится управляемой в иерархическом порядке.

Класс, который наследует свойства другого, известен как подкласс(производный класс, дочерний класс), а класс, свойства которого наследуются, называется суперклассом (базовый класс, родительский класс).

extends – это ключевое слово, используемое для обозначения наследования свойств класса.

Это важная часть ООП (объектно-ориентированного программирования).

Синтаксис наследования на Java

Пример наследования, здесь есть два класса, а именно: Calculation и My_Calculation.

Используя ключевое слово extends, My_Calculation наследует методы addition() и Subtraction() класса Calculation.

Скопируйте и вставьте следующую программу в файл с именем My_Calculation.java

Скомпилируйте и выполните приведенный выше код, как показано ниже.

После выполнения программы она даст следующий результат –
The sum of the given numbers:30
The difference between the given numbers:10
The product of the given numbers:200

В данной программе, когда создается объект класса My_Calculation, в нем создается копия содержимого суперкласса. Вот почему, используя объект подкласса, вы можете получить доступ к членам суперкласса.

наследование Java

Переменная суперкласса может содержать объект подкласса, но с помощью этой переменной вы можете получить доступ только к членам суперкласса, поэтому для доступа к членам обоих классов рекомендуется всегда создавать ссылочную переменную для подкласса.

Теперь создадим экземпляр класса, как указано ниже. Но используя ссылочную переменную суперкласса (в данном случае cal), вы не можете вызвать метод multiplication(), который принадлежит подклассу My_Calculation.

Подкласс наследует все члены(поля, методы и вложенные классы) от своего суперкласса. Конструкторы не являются членами, поэтому они не наследуются подклассами, но конструктор суперкласса может быть вызван из подкласса.

Ключевое слово super

Ниже приведены сценарии, в которых используется ключевое слово super.

Оно используется для различения членов суперкласса от членов подкласса, если они имеют одинаковые имена. И используется для вызова конструктора суперкласса из подкласса.

Разграничение членов. Если класс наследует свойства другого класса. И если члены суперкласса имеют имена, совпадающие с подклассом, для дифференциации этих переменных мы используем ключевое слово super, как показано ниже.

программа, которая демонстрирует использование ключевого слова super. У вас есть два класса, а именно Sub_class и Super_class, оба имеют метод display() с разными реализациями и переменную с именем num с разными значениями.

Мы вызываем метод display() обоих классов и печатаем значение переменной num обоих классов. Здесь вы можете заметить, что мы использовали ключевое слово super, чтобы отличать членов суперкласса от подкласса.

Скопируйте и вставьте программу в файл с именем Sub_class.java.

Скомпилируйте и выполните приведенный выше код, используя следующий синтаксис.

Результат
This is the display method of subclass
This is the display method of superclass
value of the variable named num in sub class:10
value of the variable named num in super class:20

Вызов конструктора суперкласса

Если класс наследует свойства другого класса, подкласс автоматически получает конструктор по умолчанию суперкласса. Но если вы хотите вызвать параметризованный конструктор суперкласса, вам нужно использовать ключевое слово super.
super(values);

Покажем как использовать ключевое слово super для вызова параметризованного конструктора суперкласса. Эта программа содержит суперкласс и подкласс, где суперкласс содержит параметризованный конструктор, который принимает целочисленное значение, и мы использовали ключевое слово super для вызова параметризованного конструктора суперкласса.

Скопируйте и вставьте следующую программу в файл с именем Subclass.java

Скомпилируйте и выполните приведенный выше код, используя следующий синтаксис.

Результат
The value of the variable named age in super class is: 24

IS-A отношения

IS-A – это способ показать: этот объект является типом этого объекта. Давайте посмотрим, как ключевое слово extends используется для наследования.

Теперь, на основе приведенного выше примера, в объектно-ориентированных терминах верно следующее:

  • Животное – суперкласс класса млекопитающих.
  • Животное – суперкласс рептилий.
  • Млекопитающее и Рептилия являются подклассами класса животных.
  • Собака является подклассом классов млекопитающих и животных.

Теперь, если мы рассмотрим отношения IS-A, мы можем сказать –

  • Млекопитающее IS-A животное
  • Рептилия IS-A животное
  • Собака IS-A млекопитающее
  • Отсюда: собака тоже животное

С использованием ключевого слова extends подклассы смогут наследовать все свойства суперкласса, за исключением частных свойств суперкласса.

Мы можем гарантировать, что млекопитающее на самом деле является животным с использованием оператора экземпляра.

И результат
true
true
true

Покажем как ключевое слово Implements используется для получения отношения IS-A.

Обычно ключевое слово Implements используется с классами для наследования свойств интерфейса. Интерфейсы никогда не могут быть расширены классом.

Что такое ключевое слово instanceof в Java?

Оператор java instanceof используется для проверки того, является ли объект экземпляром указанного типа (класс, подкласс или интерфейс).

Instanceof также известен как оператор сравнения типов, потому что он сравнивает экземпляр с типом. Возвращает либо true, либо false. Если мы применяем оператор instanceof к любой переменной, которая имеет нулевое значение, она возвращает false.

Если мы применяем оператор instanceof к переменной с нулевым значением, он возвращает false.

Давайте воспользуемся оператором instanceof, чтобы проверить, действительно ли млекопитающее является животным, а собака на самом деле животным.

Результат будет получен:
true
true
true

HAS-A отношения

HAS-A определяет, есть ли у определенного класса определенная вещь. Это соотношение помогает уменьшить дублирование кода и ошибок.

Это показывает, что класс Van имеет Speed(скорость). Имея отдельный класс скорости, нам не нужно помещать весь код, принадлежащий скорости, в класс Van, что позволяет повторно использовать класс скорости в нескольких приложениях.

В объектно-ориентированной функции на Java пользователям не нужно беспокоиться о том, какой объект выполняет работу. Для этого класс Van скрывает детали реализации от пользователей класса Van.

Пользователи просят класс Van выполнить определенное действие, и класс Van либо сделает работу сам по себе, либо попросит другой класс выполнить действие.

Типы наследования

Существуют различные типы наследования на Java, как показано ниже.

типы

Java не поддерживает множественное наследование. Это означает, что класс не может расширять более одного класса. Поэтому следующий код не сработает:

Однако класс может реализовать один или несколько интерфейсов, что помогло избавиться от невозможности множественного наследования.

Чтобы никто не мог наследовать класс просто используйте модификатор доступа final перед названием класса. (final class Nameclass <> )

Средняя оценка / 5. Количество голосов:

Спасибо, помогите другим — напишите комментарий, добавьте информации к статье.

Inheritance

In the preceding lessons, you have seen inheritance mentioned several times. In the Java language, classes can be derived from other classes, thereby inheriting fields and methods from those classes.

Definitions: A class that is derived from another class is called a subclass (also a derived class, extended class, or child class). The class from which the subclass is derived is called a superclass (also a base class or a parent class).

Excepting Object , which has no superclass, every class has one and only one direct superclass (single inheritance). In the absence of any other explicit superclass, every class is implicitly a subclass of Object .

Classes can be derived from classes that are derived from classes that are derived from classes, and so on, and ultimately derived from the topmost class, Object . Such a class is said to be descended from all the classes in the inheritance chain stretching back to Object .

The idea of inheritance is simple but powerful: When you want to create a new class and there is already a class that includes some of the code that you want, you can derive your new class from the existing class. In doing this, you can reuse the fields and methods of the existing class without having to write (and debug!) them yourself.

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

The Java Platform Class Hierarchy

The Object class, defined in the java.lang package, defines and implements behavior common to all classes—including the ones that you write. In the Java platform, many classes derive directly from Object , other classes derive from some of those classes, and so on, forming a hierarchy of classes.

All Classes in the Java Platform are Descendants of Object

At the top of the hierarchy, Object is the most general of all classes. Classes near the bottom of the hierarchy provide more specialized behavior.

An Example of Inheritance

Here is the sample code for a possible implementation of a Bicycle class that was presented in the Classes and Objects lesson:

A class declaration for a MountainBike class that is a subclass of Bicycle might look like this:

MountainBike inherits all the fields and methods of Bicycle and adds the field seatHeight and a method to set it. Except for the constructor, it is as if you had written a new MountainBike class entirely from scratch, with four fields and five methods. However, you didn’t have to do all the work. This would be especially valuable if the methods in the Bicycle class were complex and had taken substantial time to debug.

What You Can Do in a Subclass

A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. If the subclass is in the same package as its parent, it also inherits the package-private members of the parent. You can use the inherited members as is, replace them, hide them, or supplement them with new members:

  • The inherited fields can be used directly, just like any other fields.
  • You can declare a field in the subclass with the same name as the one in the superclass, thus hiding it (not recommended).
  • You can declare new fields in the subclass that are not in the superclass.
  • The inherited methods can be used directly as they are.
  • You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it.
  • You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
  • You can declare new methods in the subclass that are not in the superclass.
  • You can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super .

The following sections in this lesson will expand on these topics.

Private Members in a Superclass

A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.

A nested class has access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.

Casting Objects

We have seen that an object is of the data type of the class from which it was instantiated. For example, if we write

then myBike is of type MountainBike .

MountainBike is descended from Bicycle and Object . Therefore, a MountainBike is a Bicycle and is also an Object , and it can be used wherever Bicycle or Object objects are called for.

The reverse is not necessarily true: a Bicycle may be a MountainBike , but it isn’t necessarily. Similarly, an Object may be a Bicycle or a MountainBike , but it isn’t necessarily.

Casting shows the use of an object of one type in place of another type, among the objects permitted by inheritance and implementations. For example, if we write

then obj is both an Object and a MountainBike (until such time as obj is assigned another object that is not a MountainBike ). This is called implicit casting.

If, on the other hand, we write

we would get a compile-time error because obj is not known to the compiler to be a MountainBike . However, we can tell the compiler that we promise to assign a MountainBike to obj by explicit casting:

This cast inserts a runtime check that obj is assigned a MountainBike so that the compiler can safely assume that obj is a MountainBike . If obj is not a MountainBike at runtime, an exception will be thrown.

Note: You can make a logical test as to the type of a particular object using the instanceof operator. This can save you from a runtime error owing to an improper cast. For example:

Here the instanceof operator verifies that obj refers to a MountainBike so that we can make the cast with knowledge that there will be no runtime exception thrown.

Previous page: Questions and Exercises: Interfaces
Next page: Multiple Inheritance of State, Implementation, and Type

Java. Наследование (inheritance). Основные понятия. Суперкласс и подкласс. Ключевое слово extends. Скрытие данных в унаследованных классах. Модификаторы доступа private, protected, public

Наследование (inheritance). Основные понятия. Суперкласс и подкласс. Ключевое слово extends . Скрытие данных в унаследованных классах. Модификаторы доступа private , protected , public

Содержание

  • 1. В чем состоит суть наследования в классах? Что такое наследование?
  • 2. Какой класс в технологии Java есть суперклассом для всех новосозданных классов?
  • 3. Какой синтаксис наследования классов? Общая форма наследования
  • 4. Какие модификаторы доступа можно использовать к членам данных и методам класса при наследовании?
  • 5. Какие особенности использования модификатора доступа private в случае унаследованных (производных) классов?
  • 6. Какие особенности использования модификатора доступа protected в случае унаследованных классов?
  • 7. Какие особенности использования модификатора доступа public для унаследованных классов?
  • 8. Пример, который демонстрирует доступ к данным суперкласса из подкласса
  • 9. Какой тип доступа имеет член данных или метод класса, который не имеет модификатора доступа в своем объявлении? Пример
  • 10. Может ли класс наследовать другой класс, который размещается в другом пакете?

Поиск на других ресурсах:

1. В чем состоит суть наследования в классах? Что такое наследование?

С точки зрения объектно-ориентированного программирования наследование – это использование классом программного кода другого класса (классов) с целью его использования, модификации, расширения. Наследование – это одно из преимуществ объектно-ориентированного программирования в сравнении с процедурно-ориентированным.

При наследовании новый (унаследованный, производный) класс есть специализацией уже существующего класса. В данном случае термины «унаследованный» и «производный» считаются синонимами.

В случае наследования в целом разделяют два класса:

  • базовый класс (base class) или суперкласс – это класс, который служит основой для другого (других классов). В терминологии языка Java используется термин суперкласс;
  • производный класс (derived class) или подкласс – это класс, который наследует код базового класса. В терминологии Java используется термин подкласс. Подкласс имеет возможность дополнять базовый класс дополнительными полями и методами. Также подкласс имеет возможность «перегружать» или переопределять методы суперкласса.

Организацией наследования занимается компилятор.

2. Какой класс в технологии Java есть суперклассом для всех новосозданных классов?

Если создается новый класс, который не имеет суперкласса, то этот класс всегда есть производным от стандартного класса Object . Класс Object есть суперклассом для всех новосозданных классов Java.

3. Какой синтаксис наследования классов? Общая форма наследования

При наследовании классов используется ключевое слово extends . Если класс B наследует данные и методы класса A , то синтаксис наследования выглядит следующим образом:

4. Какие модификаторы доступа можно использовать к членам данных и методам класса при наследовании?

К членам данных и методам класса можно применять следующие модификаторы доступа:

  • private . В этом случае член данных класса или метод класса доступен только из методов данного класса. Из методов подклассов и объектов (экземпляров) данного класса доступа нет;
  • protected (защищенный доступ). В этом случае есть доступ из данного класса, объекта этого класса а также подкласса. Тем не менее, нет доступа из объекта подкласса;
  • public . В этом случае есть доступ из данного класса, подкласса, объекта данного класса а также объекта подкласса.

Также член данных класса или метод класса может быть объявлен в классе без использования любого модификатора (см. п. 9).

5. Какие особенности использования модификатора доступа private в случае унаследованных (производных) классов?

Если члены данных или методы класса объявлены с модификатором доступа private , тогда они считаются:

  • доступными из методов класса, в котором они объявлены;
  • недоступными для всех других методов любых классов (подклассов), экземпляров (объектов) любых классов.
6. Какие особенности использования модификатора доступа protected в случае унаследованных классов?

Если члены данных или методы класса объявлены с модификатором доступа protected , тогда они считаются:

  • доступными из методов класса, в котором они объявлены;
  • доступными из методов подкласса. Это касается и случая, когда унаследованный класс объявляется в другом пакете;
  • доступными из экземпляров (объектов) данного класса;
  • доступными из экземпляров (объектов) подкласса.
7. Какие особенности использования модификатора доступа public для унаследованных классов?

Модификатор доступа public применяется если нужно получить доступ к члену данных или методу класса из любой точки программы. Доступ к public членам данных и методам класса имеют:

  • методы данного класса;
  • методы подкласса;
  • объекты данного класса;
  • объекты подкласса;
  • объекты, которые объявлены в методах классов, которые находятся в других пакетах.
8. Пример, который демонстрирует доступ к данным суперкласса из подкласса

В примере демонстрируется доступ к членам данных класса A из подкласса B . Класс B наследует члены данных класса A .

Класс A содержит три целочисленных члена данных, которые объявлены с разными модификаторами доступа:

  • a – объявлен как private . Доступ к такому члену данных возможен только из методов класса A ;
  • b – объявлен как protected . Доступ к такому члену данных возможен только из методов класса A и подклассов. В нашем случае подклассом есть класс B . Поэтому из методов подкласса B можно использовать член данных b суперкласса A ;
  • c – объявлен как public . Доступ к такому члену данных возможен из методов класса A , методов подклассов, объектов класса A и объектов подклассов.

Ниже приведен код, который демонстрирует применение модификаторов доступа private , protected , public

9. Какой тип доступа имеет член данных или метод класса, который не имеет модификатора доступа в своем объявлении? Пример

Перед объявлением члена данных класса не обязательно ставить модификатор доступа ( private , protected , public ). Возможен случай, когда модификатор доступа не ставится. В этом случае член данных класса или метод класса есть:

  • доступен из методов данного класса;
  • доступен из всех методов классов, которые реализованы в данном пакете (пакетный доступ). Это касается и подклассов, которые реализованы в данном пакете. В этом случае тип доступа считается как public , но в пределах пакета. За пределами пакета такой элемент класса недоступен;
  • недоступен для любых методов других классов, которые размещаются в других пакетах. Это касается и подклассов.

Пример. Продемонстрировано объявление члена данных класса C без модификатора доступа.

В данном случае член данных x класса C есть видимым в пределах пакета. Более подробно о пакетах в Java описывается здесь .

10. Может ли класс наследовать другой класс, который размещается в другом пакете?

Да. В этом случае правила наследования такие же, как и в случае с классами, реализованными в одном пакете.

Горин Павел/ автор статьи

Павел Горин — психолог и автор популярных статей о внутреннем мире человека. Он работает с темами самооценки, отношений и личного роста. Его экспертность основана на практическом консультировании и современных психологических подходах.

Понравилась статья? Поделиться с друзьями:
psihologiya-otnosheniy.ru
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: