Термин наследование обозначает что производные классы содержат поля и методы родительского

Обновлено: 28.04.2024

Этот урок мы посвятим одной из ключевых тем объектно-ориентированного программирования – теме наследования. Благодаря реализации наследования мы можем организовать связь классов по принципу родительский-дочерний и добавлять дополнительную функциональность в разрабатываемые приложения без необходимости дублирования целых блоков кода.

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

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

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

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

Как наследовать от другого класса?

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

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

Синтаксис

В приведенном ниже примере класс SportsCar наследует класс Car , поэтому у него есть доступ ко всем методам и свойствам Car , которые не являются приватными. Это позволяет нам писать общедоступные методы setModel() и hello() только один раз в родительском классе, а затем использовать эти методы как в родительском, так и в дочернем классах:

Пример

Результат выполнения кода:

Собственные методы и свойства дочернего класса

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

В приведенном ниже примере мы добавим в дочерний класс некоторый собственный код, добавив свойство $style , а также метод driveItWithStyle() :

Пример

Результат выполнения кода:

Наследование и модификатор защищенного доступа

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

В этом уроке мы узнаем о третьем модификаторе — protected , который позволяет использовать код как внутри класса, так и из его дочерних классов.

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

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

Пример

Результат выполнения кода:

Мы не вывели значение модели автомобиля $model , потому что метод hello() в дочернем классе пытается получить доступ к приватному свойству $model , которое принадлежит родительскому классу.

Мы можем решить эту проблему, объявив свойство $model в родительском классе как защищенное protected , а не приватное, потому что, когда мы объявляем свойство или метод как защищенные, мы можем обращаться к нему как из родительского, так и из дочернего классов:

Пример

Результат выполнения кода:

Сказанное выше относится и к методам:

Пример

Результат выполнения кода:

Публичный метод message() дочернего класса SportsCar имеет доступ к методу intro() (который защищен) родительского класса.

Переопределение родительских свойств и методов

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

Посмотрите на пример ниже. Методы __construct() и intro() в дочернем классе (SportsCar) переопределят методы __construct() и intro() в родительском классе (Car):

Пример

Результат выполнения кода:

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

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

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

Пример

Результат выполнения кода:

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

Пример

Результат выполнения кода:

Попытка переопределить родительский метод intro(), защищенный ключевым словом final , привела к ошибке.

Заключение

Мы используем наследование, чтобы уменьшить дублирование кода за счет использования кода из родительского класса в дочерних классах. В этом уроке мы изучили один из принципов объектно-ориентированного программирования — концепцию наследования. Мы используем наследование, чтобы уменьшить дублирование кода, используя код родительского класса в дочерних классах. Щелкните здесь, чтобы попрактиковаться в предмете.

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

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


В диаграмме, представленной выше, Фрукт является родительским классом, а Яблоко и Банан — дочерними классами.


В этой диаграмме Треугольник является дочерним классом (родитель — Фигура ) и родительским (для Правильного треугольника ) одновременно.

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

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

Класс Human

Вот простой класс Human для представления Человека:

В этом классе мы определили только те члены, которые являются общими для всех объектов этого класса. Каждый Человек (независимо от пола, профессии и т.д.) имеет Имя и Возраст.

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

Класс BasketballPlayer

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

Вот наш незавершенный класс BasketballPlayer:

Также нам нужно знать Имя и Возраст баскетболиста, а эта информация уже у нас есть: она хранится в классе Human.

У нас есть три варианта добавления Имени и Возраста в BasketballPlayer:

Добавить Имя и Возраст в класс BasketballPlayer непосредственно в качестве членов. Это плохой вариант, так как произойдет дублирование кода, который уже существует в классе Human. Любые обновления в Human также должны быть продублированы и в BasketballPlayer.

Делаем класс BasketballPlayer дочерним

Чтобы класс BasketballPlayer унаследовал информацию от класса Human, нам нужно после объявления BasketballPlayer ( class BasketballPlayer ) использовать двоеточие, ключевое слово public и имя класса, от которого мы хотим унаследовать. Это называется открытым наследованием:


Когда BasketballPlayer наследует свойства класса Human, то BasketballPlayer приобретает методы и переменные-члены класса Human. Кроме того, BasketballPlayer имеет еще два своих собственных члена: m_gameAverage и m_points . Здесь есть смысл, так как эти свойства специфичны только для BasketballPlayer, а не для каждого Human-а.

Таким образом, объекты BasketballPlayer будут иметь 4 члена:

m_gameAverage и m_points от BasketballPlayer;

m_name и m_age от Human.

Полный код программы:

std :: cout anton . getName ( ) '\n' ; // используем метод getName(), который мы унаследовали от класса Human

Результат выполнения программы:

Это работает, так как anton является объектом класса BasketballPlayer, а все объекты класса BasketballPlayer имеют переменную-член m_name и метод getName(), унаследованные от класса Human.

Дочерний класс Employee

Работник наследует m_name и m_age от Human-а (а также два метода) и имеет еще две собственные переменные-члены и один метод. Обратите внимание, метод printNameAndWage() использует переменные как из класса, к которому принадлежит ( Employee::m_wage ), так и с родительского класса ( Human::m_name ).


Обратите внимание, классы Employee и BasketballPlayer не имеют прямых отношений, хотя оба наследуют свойства класса Human.

Результат выполнения программы:

Цепочка наследований


Все объекты Supervisor наследуют методы и переменные от Employee и Human, а также имеют свою собственную переменную-член m_nOverseesIDs .

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

Почему наследование является полезным?

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

Например, если мы добавим новый метод в Human, то Employee и Supervisor автоматически получат доступ к нему. Если мы добавим новую переменную в Employee, Supervisor также получит доступ к ней. Это позволяет создавать новые классы более простым, интуитивно-понятным способом!

Заключение

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

Аннотация: В данной лекции рассматривается простое и множественное наследование классов. Виртуальные методы. Абстрактные классы. Создание и использование шаблонов классов.

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

Презентацию к лекции Вы можете скачать здесь.

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

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

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

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

Если базовых классов несколько, они перечисляются через запятую. Перед каждым может стоять свой модификатор наследования . По умолчанию для классов он private , а для структур - public .

Если задан модификатор наследования public , оно называется открытым. Использование модификатора protected делает наследование защищенным, а модификатора private - закрытым. Это не просто названия: в зависимости от вида наследования классы ведут себя по-разному. Класс может наследовать от структуры, и наоборот.

До сих пор мы рассматривали только спецификаторы доступа private и public , применяемые к элементам класса. Для любого элемента класса может также использоваться спецификатор protected , который для одиночных классов, не входящих в иерархию, равносилен private . Разница между ними проявляется при наследовании . Возможные сочетания модификаторов и спецификаторов доступа приведены в таблице:

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

Элементы protected при наследовании с ключом private становятся в производном классе private , в остальных случаях права доступа к ним не изменяются.

Доступ к элементам public при наследовании становится соответствующим ключу доступа.

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

Простое наследование

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

Создадим производный от класса monster класс daemon , добавив полезную в некоторых случаях способность думать:

В классе daemon введено поле brain и метод think , определены собственные конструкторы и операция присваивания , а также переопределен метод отрисовки draw . Все поля класса monster , операции (кроме присваивания ) и методы get_health , get_ammo и set_health наследуются в классе daemon , а деструктор формируется по умолчанию.

Рассмотрим правила наследования различных методов.

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

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

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

Не наследуется и операция присваивания, поэтому ее также требуется явно определить в классе daemon . Обратите внимание на запись функции-операции: в ее теле применен явный вызов функции- операции присваивания из базового класса . Чтобы лучше представить себе синтаксис вызова, ключевое слово operator вместе со знаком операции можно интерпретировать как имя функции -операции.

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

Правила для деструкторов при наследовании :

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

Поля, унаследованные из класса monster , недоступны функциям производного класса , поскольку они определены в базовом классе как private . Если функциям, определенным в daemon , требуется работать с этими полями, можно либо описать их в базовом классе как protected , либо обращаться к ним с помощью функций из monster , либо явно переопределить их в daemon так, как было показано в предыдущем разделе.

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

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

Рассматривая наследование методов, обратите внимание на то, что в классе daemon описан метод draw , переопределяющий метод с тем же именем в классе monster (поскольку отрисовка различных персонажей, естественно, выполняется по-разному). Таким образом, производный класс может не только дополнять, но и корректировать поведение базового класса . Доступ к переопределенному методу базового класса для производного класса выполняется через уточненное с помощью операции доступа к области видимости имя.

Класс-потомок наследует все методы базового класса , кроме конструкторов, деструктора и операции присваивания . Не наследуются ни дружественные функции, ни дружественные отношения классов.

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

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

В этом уроке вы узнаете

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

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

Одиночное наследование:

В Single Inheritance один класс расширяет другой класс (только один класс).

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

На приведенной выше диаграмме класс B расширяет только класс A. Класс A является суперклассом, а класс B является подклассом.

Множественное наследование:

В множественном наследовании один класс расширяет несколько классов. Java не поддерживает множественное наследование.

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

Согласно приведенной выше диаграмме, класс C расширяет класс A и класс B.

Многоуровневое наследование:

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

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

Как показано на схеме, класс C является подклассом B, а B является подклассом класса A.

Иерархическое наследование:

В иерархическом наследовании один класс наследуется многими подклассами.

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

Как в примере выше, классы B, C и D наследуют один и тот же класс A.

Гибридное наследование:

Гибридное наследование представляет собой комбинацию одиночного и множественного наследования.

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

Как в приведенном выше примере, все открытые и защищенные члены класса A наследуются в класс D, сначала через класс B, а затем через класс C.

Примечание: Java не поддерживает гибридное / множественное наследование

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

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

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

Наследование в примере Java

Супер Ключевое слово

Ключевое слово super похоже на ключевое слово this.

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

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

Изучить наследование в ООП с примером

Рассмотрим то же банковское приложение из предыдущего примера.

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

Наследование Java и полиморфизм

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

  1. Один вывести
  2. И другой для депозитного действия.

Поскольку работа этих функций остается одинаковой для всех учетных записей.

Наследование Java и полиморфизм

Подход ООП : при использовании подхода программирования ООП. Мы бы создали два класса.

  • У каждого есть реализация функций пополнения и снятия.
  • Это будет лишней дополнительной работой.

Наследование Java и полиморфизм

Запрос на изменение в программном обеспечении

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

Наследование Java и полиморфизм

Структурный подход: используя функциональный подход, я должен изменить свою функцию вывода, которая уже проверена и обоснована. И добавьте метод, как показано ниже, позаботится о новых требованиях.

Наследование Java и полиморфизм

Подход ООП: Используя подход ООП, вам просто нужно написать новый класс с уникальной реализацией функции изъятия. Мы никогда не трогали проверенный кусок кода.

Наследование Java и полиморфизм

Еще один запрос на изменение

Что если требование изменится дальше? Как добавить учетную запись кредитной карты со своим собственным уникальным требованием депозитов .

Наследование Java и полиморфизм

Структурный подход. Используя структурный подход, вы должны снова изменить проверенный код депозита.

Наследование Java и полиморфизм

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

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

Наследование Java и полиморфизм

Преимущество наследования в ООП

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

Функции не должны быть реализованы индивидуально. Это наследование в Java. ,

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

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

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

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

Если в классе-наследнике имя метода и его прототип совпадают с именем метода базового класса, то говорят, что метод производного классаскрывает метод базового класса. Чтобы вызвать метод родительского класса, нужно указывать его с квалификатором класса.

Объекты класса-наследника могут использовать операции базового класса.

Операция присваивания и принцип подстановки

Помимо конструкторов, не наследуются два вида функций: операция присваивания и дружественные функции.

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

Операция бинарная, левым аргументом является текущий объект. Эта стандартная операция обеспечивает копирование значений полей объекта t в поля текущего объекта. Для базового класса Base и его наследника Derive соответствующие операции присваивания имеют вид:

Наличие этих функций позволяет выполнять следующие присваивания:

Base b1,b2; // переменные базового класса

Derive dl,d2; // переменные производного класса

b1 = b2; // операция базового класса

dl = d2; // операция производного класса

// базовый=производный; операция базового класса

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

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

При перегрузке операций для классов, находящихся в отношении наследования появляются особенности.

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




Рассмотрим пример1 программы, демонстрирующей особенности обращений из дружественных функций производного класса к дружественным функциям базового класса. В данном примере ввод-вывод объектов наследников изменяется.

using namespace std;

protected: int k;

friend ostream& operator >(istream& stream,Base &ob)

Сначала мы опишем класс Point. Затем - класс Circle, который является производным классом от класса Point. И, наконец, - класс Cylinder, который является наследником класса Circle.

using namespace std;

protected://доступно для производных классов

double x,y; //координаты Point x и y

// конструктор с умолчанием

double getX() // получение x

double getY() // получение y

friend ostream& operator >(istream & stream,Point &ob)

//Класс Circle наследует

//классу Point путем открытого наследования

//Circle наследует Point

class Circle:public Point

protected://доступно для производных классов

//конструктор с умолчанием

Circle(double r=0.0,double x=0,double y=0);

void setRadius(double); //установка радиуса

double getRadius(); //возвращение радиуса

double area(); //вычисление площади круга

friend ostream& operator >(istream& stream,Circle &ob)

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

Создать многофайловый проект.

Вариант 1

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

Вариант 2

Создать класс Pair (пара чисел); определить методы изменения полей и сравнения пар: пара p1 больше пары р2, если (first.p1 > first.p2) или (first.p1 = first.р2) и (second.p1 > second.р2). Определить класс-наследник Fraction с полями: целая часть числа и дробная часть числа. Определить полный набор методов сравнения.

Вариант 3

Создать класс Liquid (жидкость), имеющий поля названия и плотности. Определить методы переназначения и изменения плотности. Создать производный класс Alcohol (спирт), имеющий крепость. Определить методы переназначения и изменения крепости.

Вариант 4

Создать класс Pair (пара чисел); определить методы изменения полей и вычисления произведения чисел. Определить производный класс Rectangle (прямоугольник) с полями-сторонами. Определить методы вычисления периметра и площади прямоугольника.

Вариант 5

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

Вариант 6

Создать класс Triad (тройка чисел); определить методы изменения полей и вычисления суммы чисел. Определить производный класс Triangle с полями-сторонами. Определить методы вычисления углов и площади треугольника.

Вариант 7

Создать класс Triangle с полями-сторонами. Определить методы изменения сторон, вычисления углов, вычисления периметра. Создать производный класс Equilateral (равносторонний), имеющий поле площади. Определить метод вычисления площади.

Вариант 8

Создать класс Triangle с полями-сторонами. Определить методы изменения сторон, вычисления углов, вычисления периметра. Создать производный класс RightAngled (прямоугольный), имеющий поле площади. Определить метод вычисления площади.

Вариант 9

Создать класс Pair (пара чисел); определить методы изменения полей и вычисления произведения чисел. Определить производный класс RightAngled с полями-катетами. Определить методы вычисления гипотенузы и площади треугольника.

Вариант 10

Создать класс Triad (тройка чисел); определить метод сравнения триад (аналогично варианту 2). Определить производный класс Date с полями: год, месяц и день. Определить полный набор методов сравнения дат.

Вариант 11

Создать класс Triad (тройка чисел); определить метод сравнения триад (аналогично варианту 2). Определить производный класс Time с полями: час, минута и секунда. Определить полный набор методов сравнения моментов времени.

Вариант 12

Реализовать класс-оболочку Number для числового типа float. Реализовать методы сложения и деления. Создать производный класс Real, в котором реализовать метод возведения в произвольную степень, и метод для вычисления логарифма числа.

Вариант 13

Создать класс Triad (тройка чисел); определить методы увеличения полей на 1. Определить производный класс Date с полями: год, месяц и день. Переопределить методы увеличения полей на 1 и определить метод увеличения даты на n дней.

Вариант 14

Реализовать класс-оболочку Number для числового типа double. Реализовать методы умножения и вычитания. Создать производный класс Real, в котором реализовать метод, вычисляющий корень произвольной степени, и метод для вычисления числа n в данной степени.

Вариант 15

Создать класс Triad (тройка чисел); определить методы увеличения полей на 1. Определить класс-наследник Time с полями: час, минута, секунда. Переопределить методы увеличения полей на 1 и определить методы увеличения на n секунд и минут.

Вариант 16

Создать базовый класс Pair (пара целых чисел) с операциями проверки на равенство и перемножения полей. Реализовать операцию вычитания пар по формуле (а, b) - (с, d) = (а - b, с - d). Создать производный класс Rational; определить новые операции сложения (a, b) + (с, d) = (ad + be, bd) и деления (a, b) / (с, d) = (ad, bc), переопределить операцию вычитания (a, b) - (с, d) = = (ad - be, bd).

Вариант 17

Создать класс Pair (пара чисел); определить метод перемножения полей и операцию сложения пар (а, b) + (с, d) = (а + b, с + d). Определить производный класс Complex с полями: действительная и мнимая части числа. Определить методы умножения (а, b)*(c,d) = (ас - bd, ad + be) и вычитания (а, b) - - (с, d) = (а - b, с - d).

Вариант 18

Создать класс Pair (пара целых чисел); определить методы изменения полей и операцию сложения пар (а, b) + (с, d) = (а + b, с + d). Определить класс-наследник Long с полями: старшая часть числа и младшая часть числа. Переопределить операцию сложения и определить методы умножения и вычитания.

Вариант 19

Создать базовый класс Triad (тройка чисел) с операциями сложения с числом, умножения на число, проверки на равенство. Создать производный класс vector3D, задаваемый тройкой координат. Должны быть реализованы: операция сложения векторов, скалярное произведение векторов.

Вариант 20

Создать класс Pair (пара целых чисел); определить метод умножения на число и операцию сложения пар (а, b) + (с, d) = (а + b, с + d). Определить класс-наследник Money с полями: рубли и копейки. Переопределить операцию сложения и определить методы вычитания и деления денежных сумм.

Читайте также: