Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Базовый механизм наследованияСодержание книги
Поиск на нашем сайте
Наследование— это аспект ООП, облегчающий повторное использование кода. Существует в двух видах: классическое наследование (отношение "является" – is-a) и модель включения-делегирования (отношение "имеет" – has-a).
Модель включения-делегирования будет рассмотрена в лабораторной работе №12. Здесь рассмотрим классическую модель наследования типа "является". При установке между классами такого отношения строится зависимость между двумя или более типами классов. Базовая идея, лежащая в основе классического наследования заключается в том, что новые классы могут использовать (и, возможно, расширять) функциональность существующих классов.
Спецификация родительского класса
Теперь предположим, что планируется построить новый класс по имени TimeStarting (время отправления). Подобно базовому классу Time, необходимо, чтобы TimeStarting поддерживал шесть полей данных даты и времени и соответствующие свойства, позволяющее пользователю модифицировать состояние объекта. Ясно, что классы Time и TimeStarting взаимосвязаны; фактически можно сказать, что TimeStarting "является" Time. Отношение "является" (формально называемое классическим наследованием) позволяет строить новые определения классов, расширяющие функциональность существующих классов.
Существующий класс, который будет служить основой для нового класса, называется базовым или родительским классом. Назначение базового класса состоит в определении всех общих данных и членов для классов, которые расширяют его. Расширяющие классы формально называются производными или дочерними классами. В С# для установки между классами отношения "является" используется операция двоеточия в определении класса: class имя_класса_потомка:имя_базового_класса{ // тело класса}Имеют место следующие отличия в механизме наследования 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. Титульный лист. 2. Цель работы, индивидуальное задание (таблица). 3. Листинг программы. 4. Блок-схемы методов класса. 5. Результаты тестирования всех методов. 6. Описание различий в работе конструкторов базового и производного классов. 7. Выводы.
Лабораторная работа №10
Тема: Динамические структуры данных. Объектно-ориентированное программирование односвязного списка.
Цель: освоение составления и тестирования алгоритмов и объектно-ориентированных программ, использующих динамические структуры данных.
Теоретические положения
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2021-09-26; просмотров: 115; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.224.44.115 (0.012 с.) |