Базовый механизм наследования 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Базовый механизм наследования



 

Наследование— это аспект ООП, облегчающий повторное использование кода. Существует в двух видах: классическое наследование (отношение "является" – is-a) и модель включения-делегирования (отношение "имеет" –  has-a).

 

Модель включения-делегирования будет рассмотрена в лабораторной работе №12. Здесь рассмотрим классическую модель наследования типа "является". При установке между классами такого отношения строится зависимость между двумя или более типами классов. Базовая идея, лежащая в основе классического наследования заключается в том, что новые классы могут использовать (и, возможно, расширять) функциональность существующих классов.

 

Спецификация родительского класса

 

Теперь предположим, что планируется построить новый класс по имени TimeStarting (время отправления). Подобно базовому классу Time, необходимо, чтобы TimeStarting поддерживал шесть полей данных даты и времени и соответствующие свойства, позволяющее пользователю модифицировать состояние объекта. Ясно, что классы Time и TimeStarting взаимосвязаны; фактически можно сказать, что TimeStarting "является" Time. Отношение "является" (формально называемое классическим наследованием) позволяет строить новые определения классов, расширяющие функциональность существующих классов.

 

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

class имя_класса_потомка:имя_базового_класса{  // тело класса}

Имеют место следующие отличия в механизме наследования C# от С++:

  1. В качестве базового класса при наследовании может быть указан только один класс. Это означает, что в C# нет механизма множественного наследования. Если же необходимо выполнить его, то применяется механизм интерфейсов.
  2. При наследовании не указываются спецификаторы доступа как в C++.

Перегрузка операций

 

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

 

int[n]Array;

 

Обеспечить этот класс функциональностью базовых типов - значит, получить возможность выполнять арифметические операции над объектами класса (складывать массивы, умножать их и т. д.). Конечно, программист, определивший тип, может реализовать методы для каждой из требуемых операций. Например, если необходимо увеличить элементы массива в n раз, то можно определить метод Array.Mul(int n) и затем вызвать его из основной программы:

 

ar1.Mul(n);

 

Однако, гораздо нагляднее написать:

 

ar1 *= n;

 

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

 

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

Можно перегружать следующие унарные операторы: +, -,!, ~, ++, --, true, false

Например, пусть необходимо для класса Array перегрузить унарную операцию “–“ так, чтобы все элементы массива изменили знак:

 

   public static Array operator -(Array ar)

   {

       for (int i = 0; i < ar.n; i++)

           ar.ar[i] = -ar.ar[i];

       return ar;

   }

Можно перегружать следующие бинарные операторы: +, -, *, /, %, &, |, ^, <<, >>

Для данных операторов справедливы следующие правила: один из двух параметров функции должен быть типа класса; если в классе перегружен оператор + (например), то оператор += перегружается автоматически (это справедливо для всех вышеперечисленных бинарных операторов).

Так, чтобы перегрузить операцию сложения (+), следует написать:

public static Array operator+(Array ar1, Array ar2)

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

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

Теперь, если написать:

Array arS = ar1+ ar2;

то будет вызвана перегруженная операция +, которой переменная ar1 будет передана в качестве первого параметра, а переменная ar2 - в качестве второго. Когда компилятор встречает выражение:

ar1+ ar2

он преобразует его в:

Array.operator+(ar1, ar2)

 

В результате возвращается новое значение типа Array, которое в данном случае присваивается объекту Array с именем arS.

 

   public static Array operator +(Array ar1, Array ar2)

   {

       int n=ar1.n;

         Array arS = new Array(n);

       for (int i = 0; i < n; i++)

           arS.ar[i] = ar1.ar[i] + ar2.ar[i];

       return arS;

   }

Перегрузка оператора «*» для умноження элементов массива на число int:

   public static Array operator *(Array ar1, int m)

   {

       for (int i = 0; i < ar1.n; i++)

           ar1.ar[i] *= m;

       return ar1;

   }

Операторы сравнения ==,!=, <, >, <=, >= всегда перегружаются парами: == и!=, < и >, <= и >=. Ниже в примере показаны методы для сравнения двух строк матрицы по числу нулевых элементов, перегружающие операторы == и!=. В паре с ними желательно перегружать функцию Equals, которая наследуется из базового класса Object,, чтобы их функциональность не различалась.

Пример класса Matrix производного от базового класса Array

 

public class Matrix: Array

{

   public Matrix()

   {

       m = 5;

       n = 10;

       matr = new Array[m];

       for (int i = 0; i < m; i++)

           matr[i] = new Array(n);

       Console.WriteLine("Matrix без параметров выполнен.");

   }

 

   public Matrix(int m, int n)

   {

       this.m = m;

       this.n = n;

       matr = new Array[m];

       for (int i = 0; i < m; i++)

           matr[i] = new Array(n);

       Random rnd = new Random();

       for (int i = 0; i < m; i++)

           for (int j = 0; j < n; j++)

             matr[i].ar[j] = rnd.Next(100);

               Console.WriteLine("Matrix с параметрами выполнен.");

   }

 

   public void PrintMatrix()

   {

     for (int i = 0; i < m; i++)

         matr[i].PrintArray();

   }

 

   // Метод выполняет сортировку элементов строк матрицы по возрастанию

   // с использованием метода вставки

   public void SortMatrix()

   {

       int j,k,l,el;

       for (int i = 0; i < m; i++)

               

           for (j = 1; j < n; j++)

           {

               el = matr[i].ar[j];

               k = 0;

               while (el > matr[i].ar[k])

                   k++;

               for (l = j - 1; l >= k; l--)

                   matr[i].ar[l + 1] = matr[i].ar[l];

               matr[i].ar[k] = el;

           }

   }

 

   public static bool operator ==(Array ar1, Array ar2)

   {

       int t1, t2;

       t1 = t2 = 0;

       for (int i = 0; i < ar1.n; i++)

       {

           if (ar1.ar[i] == 0)

               ++t1;

           if (ar2.ar[i] == 0)

               ++t2;

       }

       return (t1 == t2);

   }

 

   public static bool operator!=(Array ar1, Array ar2)

   {

       return!(ar1 == ar2);

    }

 

   public override bool Equals(object obj)

   {

       try

       {

           return (bool)(this == (Array)obj);

       }

       catch

       {

           // Если obj не принадлежит классу Array

           return false;

       }

   }

 

   private int m;

   private int n;

   private Array[] matr;

}

// Конец определения производного класса Matrix

 

 

class Program

{

   static void Main(string[] args)

   {

       Matrix m0 = new Matrix();

       Console.WriteLine("\n");

       Matrix m1 = new Matrix(5,10);

       Console.WriteLine("\nИсходная матрица:");

       m1.PrintMatrix();

       m1.SortMatrix();

       Console.WriteLine("\nОтсортированная матрица:");

       m1.PrintMatrix();

 

       Console.ReadKey();

   }

}

Задание

 

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

2. На основе класса Array, реализованного в лабораторной работе №8, и согласно индивидуальному заданию (табл. 12) создать производный от него класс Matrix.

3. Дочерний класс должен содержать такие закрытые члены:

- высота матрицы;

- ссылка на массив векторов базового класса;

             а также следующие открытые методы:

- конструктор без параметров, создающий нулевую матрицу фиксированного размера; размер задается константами;

- конструктор с параметрами, создающий и инициализирующий матрицу случайных чисел в заданном диапазоне; размер задается с использованием параметров;

- метод вывода элементов матрицы на консоль;

- метод, реализующий вычисление заданного показателя P, для которого предусмотреть свойство в классе Matrix;

- метод, реализующий заданное преобразование матрицы посредством перегрузки заданного оператора;

- метод, реализующий заданную сортировку матрицы (нечетные варианты – по столбцам, четные варианты – по строкам).

Конструкторы должны выводить сообщение о своем срабатывании.

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

5. Составить блок-схему алгоритма каждого метода.

 

Таблица 12. Варианты заданий к лабораторной работе №9

№ вар. Массив и длина Интервал генерации Показатель Р Алгоритм обработки Перегружае­мый оператор Метод сортировки
1 А(10, 8) [-10, 25] Сумма произведений элементов строки и столбца матрицы, на пересечении которых находится наибольший по абсолютной величине элемент матрицы. Все отрицательные элементы, расположенные по периметру матрицы заменить их абсолютными значениями. Унарный + Вставкой
2 Х(5, 10) [-15, 10] Количество элементов матрицы, превышающих ее среднее арифметическое значение. Все положительные элементы матрицы умножить на ее среднее арифметическое значение. * Обменом
3 Y(10, 12) [-20, 10] Сумма элементов матрицы, для которых i+j=k, где k - введенное с клавиатуры зна­чение. Проверить, что значение k позволяет найти решение для каждой из матриц. Все элементы матрицы, превышающие ее среднее арифметическое значение разделить на максимальный элемент. / Выбором
4 Z(10, 7) [-30, 40] Сумма положительных элементов столбца, содержащего максимальный элемент матрицы. Все элементы столбца, содержащего минимальный элемент матрицы, уменьшить на ее среднее арифметическое значение. Унарный – Быстрая (рекурсив­ная)
5 В(6, 11) [-20, 25] Разность между максимальным и мини­мальным значениями элементов массива. Все элементы строк, начинающихся с отрицательных элементов, умножить на максимальный элемент матрицы. * Шейкерная
6 С(8, 12) [-15, 75] Сумма элементов, расположенных по периметру матрицы. Столбцы матрицы упорядочить по возрастанию значений их элементов, минимальные элементы в столбцах увеличить на 1 ++ Вставкой
7 А(10, 9) [-30, 100] Среднее геометрическое элементов матрицы: Все элементы матрицы уменьшить на ее максимальное значение Бинарный – Обменом
8 Х(9, 12) [-40, 20] Отношение среднего арифметического значения к минимальному элементу матрицы. Строки матрицы упорядочить по убыванию значений их элементов, максимальные элементы в строках декрементировать –– Выбором
9 Y(10, 10) [-50, 60] Произведение ненулевых элементов строки матрицы, на которой расположен максимальный элемент. Все элементы матрицы увеличить на ее среднее арифметическое значение. Бинарный + Быстрая (рекурсив­ная)
10 Z(7, 9) [-25, 15] Сумма значений элементов матрицы, меньших ее среднего арифметического значения. Все положительные элементы строки, содержащей максимальный элемент разделить на ее среднее арифметическое значение / Шейкерная
11 T(5, 14) [-10, 5] Разность между суммой значений элементов четных и нечетных строк Элементы строк, у которых минимальные элементы положительные, увеличить на значения этих элементов. Бинарный + Вставкой
12 A(8, 8) [-5, 10] Отношение произведения ненулевых элементов к сумме положительных элементов матрицы. Элементы столбцов, у которых среднее арифметическое значение отрицательно, умножить на эти средние значения. * Обменом
13 N(12, 6) [-20, 10] Абсолютное значение произведения ненулевых элементов, принадлежащих интервалу [-2, 2] Все элементы матрицы, превышающие ее среднее арифметическое значение, возвести в степень P. ^ Выбором
14 B(11, 11) [-30, 0] Количество отрицательных элементов матрицы. Все элементы столбца, содержащего минимальный элемент матрицы, уменьшить на ее среднее арифметическое значение. Бинарный – Быстрая (рекурсив­ная)
15 M(10, 5) [-20, 25] Сумма элементов матрицы, больших ее среднего значения Элементы столбцов матрицы циклически сдвинуть влево на число положительных элементов в в них << Шейкерная
16 R(5, 12) [-15, 75] Минимальный по абсолютной величине элемент матрицы. Все элементы строк, начинающихся с отрицательных элементов, умножить на максимальный элемент матрицы. * Вставкой
17 C(10, 10) [-30, 100] Отношение сумм элементов, лежащих выше и ниже главной диагонали матрицы. У элементов строк матрицы, начинающихся с положительных значений, сменить знак Унарный – Обменом
18 F(7, 7) [-40, 20] Отношение произведения ненулевых элементов к сумме положительных элементов матрицы. Транспонировать матрицу ! Выбором
19 S(10, 4) [-40, 60] Отношение максимального и минимального элементов матрицы Все элементы матрицы уменьшить, меньше среднего арифметического, уменьшить на 1 –– Быстрая (рекурсив­ная)
20 U(6, 15) [-15, 15] Сумма элементов столбца в котором расположен максимальный элемент матрицы. Элементы строк, у которых минимальные элементы положительные, увеличить на 1 ++ Шейкерная
21 V(11, 5) [-20, 5] Разность модуля суммы отрицательных элементов и суммы положительных элементов Все элементы матрицы увеличить на ее максимальное значение Бинарный + Вставкой
22 D(9, 9) [-15, 10] Произведение ненулевых элементов, лежащих выше главной диагонали матрицы Элементы столбцов, у которых среднее арифметическое значение отрицательно, умножить на эти средние значения. * Обменом
23 L(5, 11) [-20, 20] Количество элементов матрицы, больших ее среднего значения. Все положительные элементы строки, содержащей максимальный элемент разделить на ее среднее арифметическое значение. / Выбором
24 G(8, 8) [-30, 20] Произведение элементов строк с положительными средними значениями для матрицы. Элементы столбцов матрицы, у которых среднее арифметическое значение >0 упорядочить по возрастанию. > Быстрая (рекурсив­ная)
25 K(6, 5) [-10, 55] Сумма элементов строк с нечетными индексами, не превышающих среднее значение по матрице Элементы столбцов матрицы, у которых среднее арифметическое значение <0 упорядочить по убыванию < Шейкерная
26 Q(7, 7) [0, 99] Число нулевых младших разрядов элементов матрицы Логически сдвинуть элементы строк вправо на P позиций >> Вставкой
27 Y(10, 10) [-50, 60] Максимальный из старших разрядов элементов, лежащих выше главной диагонали Логически сдвинуть элементы столбцов влево на P позиций << Обменом
28 Z(7, 9) [0, 12] Число простых чисел в матрице Возвести элементы строки, содержащей максимальный элемент, в степень P ^ Выбором
29 T(5, 14) [-10, 5] Сумма разностей элементов столбцов с максимальным и минимальным по модулю элементами Совпадающие столбцы матрицы обнулить == Быстрая (рекурсив­ная)
30 A(8, 8) [0, 10] Разность сумм элементов главной и побочной диагоналей Циклически сдвинуть элементы столбцов на P позиций >> Шейкерная

 

Содержание отчета

 

1. Титульный лист.

2. Цель работы, индивидуальное задание (таблица).

3. Листинг программы.

4. Блок-схемы методов класса.

5. Результаты тестирования всех методов.

6. Описание различий в работе конструкторов базового и производного классов.

7. Выводы.


 

Лабораторная работа №10

 

Тема: Динамические структуры данных. Объектно-ориентированное программирование односвязного списка.

 

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

 

 

Теоретические положения

 



Поделиться:


Последнее изменение этой страницы: 2021-09-26; просмотров: 102; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.117.158.47 (0.061 с.)