
C# (ИТИП) / Теоретический материал по C# Microsoft / ИЕРАРХИЯ КЛАССОВ
.pdfБолее подробно рассмотрим стандартный интерфейс IComparable.
Интерфейс IComparable определен в пространстве имен System и содержит единственный метод CompareTo, возвращающий результат сравнения двух объектов – текущего и переданного ему в качестве параметра:
interface IComparable
{
int CompareTo(object obj);
}
Реализация данного метода должна возвращать:
1)0 – если текущий объект и параметр равны;
2)отрицательное число, если текущий объект меньше параметра;
3)положительное число, если текущий объект больше параметра.
Использование стандартного интерфейса IComparable рассмотрим на
модификации класса PointPlane, приведенного в предыдущем примере.
public class PointPlane: Point, IComparable
{
…
//добавили в класс реализацию метода CompareTo public int CompareTo (object obj)
{
Point b=(Point) obj; //преобразуем параметр к типу Point
//определяем критерии сравнения текущего объекта с параметром в // зависимости от удаленности точки от начала координат
if (this.Distance()==b.Distance())
{
return 0;
}
else
{
if (this.Distance()>b.Distance())
{
return 1;
}
else
{
return -1;
}
}
}
}
Обратите внимание на то, что мы изменили только класс PointPlane, класс PointSpace мы не меняли. А теперь рассмотрим следующий фрагмент программы:
Point [] array=new Point[5]; array[0]=new PointPlane(0, 3); array[1]=new PointPlane(4, 3); array[2]=new PointSpace(0, 0, 0); array[3]=new PointSpace(1, 1, 1); array[4]=new PointPlane(-1, -2);
Array.Sort(array); //вызываем стандартную сортировку массива foreach(Point item in array)
{
item.Show();
Console.WriteLine("Расстояние до начала координат: {0:f2}", item.Distance()); Console.WriteLine();
21

}
Результат работы фрагмента программы
(0, 0, 0)
Расстояние до начала координат: 0,00
(1, 1, 1)
Расстояние до начала координат: 1,73
(-1, -2)
Расстояние до начала координат: 2,24
(0, 3)
Расстояние до начала координат: 3,00
(4, 3)
Расстояние до начала координат: 5,00
Обратите внимание на то, что во время реализации метода CompareTo в качестве параметра передавалась ссылка на объект типа object. Напомним, что класс object является корневым классом для всех остальных в С#. Поэтому он может ссылаться на объект любого типа. Но чтобы потом получить доступ к членам объекта произвольного класса, нужно выполнить приведение типов.
Таким образом, переопределив метод CompareTo, нам удалось отсортировать массив, используя стандартный метод сортировки, определенный в классе Array.
Задания.
1.Объясните, почему реализуя метод CompareTo мы привели объектную ссылку к типу Point, а не к типу PointPlane.
2.Объясните, почему в классе PointSpace мы не переопределяли метод CompareTo.
3.Измените реализацию метода CompareTo так, чтобы метод Sort сортировал массив точек по убыванию расстояния между точкой и началом координат.
Используя собственную реализацию метода CompareTo можно перегрузить операции отношения. Напомним, что операции отношения должны перегружаться парами: < и >, <= и >=, == и !=.
В следующем примере для класса PointPlane перегрузим операции == и != таким образом, чтобы при сравнении двух объектов возвращалось значение true, если точки находятся на равном удалении от начала координат, в противном случае – false. Для этого в класс PointPlane добавим следующие методы:
public static bool operator ==(PointPlane a, PointPlane b)
{
return (a.CompareTo(b)==0);
}
public static bool operator !=(PointPlane a, PointPlane b)
{
return (a.CompareTo(b)!=0);
}
Рассмотрим следующий фрагмент программы:
PointPlane a=new PointPlane(0, 3); PointPlane b=new PointPlane(3, 0); PointPlane c=new PointPlane(-1, -2); if (a==b)
{
Console.WriteLine("точки а и b равноудалены от начала координат");
}
22

else
{
Console.WriteLine("точки а и b находятся на разном расстоянии от начала координат");
}
if (a==c)
{
Console.WriteLine("точки а и c равноудалены от начала координат");
}
else
{
Console.WriteLine("точки а и c находятся на разном расстоянии от начала координат");
}
Результат работы фрагмента программы:
точки а и b равноудалены от начала координат
точки а и c находятся на разном расстоянии от начала координат
Однако если мы попытаемся выполнить следующий фрагмент программы:
Point a=new PointPlane(0, 3); Point b=new PointPlane(3, 0, 0); if (a==b)
{
Console.WriteLine("точки а и b равноудалены от начала координат");
}
else
{
Console.WriteLine("точки а и b находятся на разном расстоянии от начала координат");
}
То получим следующий результат:
точки а и b находятся на разном расстоянии от начала координат
Давайте разберемся, что произошло. Дело в том, что операторы проверки на равенство были перегружены в классе PointPlane. Абстрактный класс Point про них ничего не знает и использует стандартные операторы, которые проверяют равенство ссылок, а не объектов. Например, если заменить код создания объектов на такой:
PointPlane a = new PointPlane(0, 3);
PointPlane b = new PointSpace(3, 0, 0);
то сравнение пройдет правильно, так как ссылки на PointPlane уже знают о правилах перегрузки операторов.
Решить эту проблему нам поможет создание следующей иерархии объектов:
23

Абстрактный класс
Point
Класс точка на плоскости
PointPlane
Класс точка в пространстве
PointSpace
Рассмотрим каждый компонент иерархии типов.
Абстрактный класс Point:
using System;
namespace MyProgram
{
abstract public class Point:IComparable
{
abstract public string Name {get;} abstract public void Show(); abstract public double Distance(); abstract public int this [int i]{get; set;} public int CompareTo (object obj)
{
Point b=(Point) obj;
if (this.Distance()==b.Distance())
{
return 0;
}
else
{
if (this.Distance()>b.Distance())
{
return 1;
}
else
{
return -1;
}
}
}
public static bool operator ==(Point a, Point b)
{
return (a.CompareTo(b)==0);
}
public static bool operator !=(Point a, Point b)
{
return (a.CompareTo(b)!=0);
}
}
}
24
Класс PointPlane:
using System;
namespace MyProgram
{
public class PointPlane: Point
{
protected int x; protected int y;
readonly string name="point";
public PointPlane(int x, int y)
{
this.x=x;
this.y=y;
}
public override string Name
{
get
{
return name;
}
}
public override void Show()
{
Console.WriteLine("({0}, {1})", x, y);
}
public override double Distance()
{
return Math.Sqrt(x*x+y*y);
}
public override int this [int i]
{
get
{
if (i==1)
{
return x;
}
else
{
if (i==2)
{
return y;
}
else
{
Console.WriteLine("Неверно указан индекс"); return 0;
}
}
}
set
25
{
if (i==1)
{
x=value;
}
else
{
if (i==2)
{
y=value;
}
else
{
Console.WriteLine("Неверно указан индекс");
}
}
}
}
}
}
Класс PointSpace:
using System;
namespace MyProgram
{
public class PointSpace:PointPlane
{
protected int z;
public PointSpace(int x, int y, int z):base (x, y)
{
this.z=z;
}
public new void Show()
{
Console.WriteLine("({0}, {1}, {2})", x, y, z);
}
public new double Distance()
{
return Math.Sqrt(x*x+y*y+z*z);
}
public new int this [int i]
{
get
{
if (i==1)
{
return x;
}
else
{
if (i==2)
{
26
return y;
}
else
{
if (i==3)
{
return z;
}
else
{
Console.WriteLine("Неверно указан индекс"); return 0;
}
}
}
}
set
{
if (i==1)
{
x=value;
}
else
{
if (i==2)
{
y=value;
}
else
{
if (i==3)
{
z=value;
}
else
{
Console.WriteLine("Неверно указан индекс");
}
}
}
}
}
}
}
Рассмотрим, как теперь будут сравниваться между собой разнотипные объекты:
Point a=new PointPlane(0, 3); Point b=new PointSpace(3, 0, 0); Point c=new PointSpace(3, 0, 1); if (a==b)
{
Console.WriteLine("точки а и b равноудалены от начала координат");
}
else
{
Console.WriteLine("точки а и b находятся на разном расстоянии от начала координат");
}
27

if (a==c)
{
Console.WriteLine("точки а и c равноудалены от начала координат");
}
else
{
Console.WriteLine("точки а и c находятся на разном расстоянии от начала координат");
}
Результат работы фрагмента программы:
точки а и b равноудалены от начала координат
точки а и c находятся на разном расстоянии от начала координат
Задание для самостоятельной работы
Замечания.
1)Полную структуру классов и их взаимосвязь продумать самостоятельно.
2)Для абстрактного класса определить, какие методы должны быть абстрактными, а какие обычными.
3)Исходные данные считываются из файла.
Задание 1
1.Создать абстрактный класс Figure с функциями вычисления площади и периметра, а также функцией, выводящей информацию о фигуре на экран.
2.В абстрактном классе Figure реализовать метод CompareTo так, чтобы можно было отсортировать объекты по их площадям.
3.Создать производные классы: Rectangle (прямоугольник), Circle (круг), Triangle (треугольник).
4.Создать массив n фигур и вывести полную информацию о фигурах на экран, отсортировав объекты по их площадям.
Задание 2
1.Создать абстрактный класс Function с функциями вычисления значения по формуле y=f(x) в заданной точке, а также функцией, выводящей информацию о виде функции на экран.
2.В абстрактном классе Function реализовать метод CompareTo так, чтобы можно было отсортировать функции по коэффициенту a.
3.Создать производные классы: Line (y=ax+b), Kub (y=ax2+bx+c), Hyperbola (y=a/x).
4.Создать массив n функций и вывести полную информацию о значении данных функций в точке х, отсортировав функции по коэффициенту a.
Задание 3
1.Создать абстрактный класс Edition с функциями, позволяющими вывести на экран информацию об издании, а также определить, является ли данное издание искомым.
2.В абстрактном классе Edition реализовать метод CompareTo так, чтобы можно было отсортировать каталог изданий по фамилии автора.
3.Создать производные классы: Book (название, фамилия автора, год издания, издательство), Article (название, фамилия автора, название журнала, его номер и год издания), OnlineResource (название, фамилия автора, ссылка, аннотация).
4.Создать каталог (массив) из n изданий, вывести полную информацию из каталога, отсортировав каталог изданий по фамилии автора, а также организовать поиск изданий по фамилии автора.
Задание 4
28
1.Создать абстрактный класс Transport с функциями, позволяющими вывести на экран информацию о транспортном средстве, а также определить грузоподъемность транспортного средства.
2.В абстрактном классе Transport реализовать метод CompareTo так, чтобы можно было отсортировать базу данных о машинах по их грузоподъемности.
3.Создать производные классы: Car (марка, номер, скорость, грузоподъемность), Motorbike (марка, номер, скорость, грузоподъемность, наличие коляски, при этом если коляска отсутствует, то грузоподъемность равна 0), Truck (марка, номер, скорость, грузоподъемность, наличие прицепа, при этом если есть прицеп, то грузоподъемность увеличивается в два раза).
4.Создать базу (массив) из n машин, вывести полную информацию из базы на экран, отсортировав базу данных о машинах по их грузоподъемности, а также организовать поиск машин, удовлетворяющих требованиям грузоподъемности.
Задание 5
1.Создать абстрактный класс Persona с функциями, позволяющими вывести на экран информацию о персоне, а также определить ее возраст (на момент текущей даты).
2.В абстрактном классе Persona реализовать метод CompareTo так, чтобы можно было отсортировать базу данных о персонах по дате рождения.
3.Создать производные классы: Enrollee (фамилия, дата рождения, факультет), Student (фамилия, дата рождения, факультет, курс), Teacher (фамилия, дата рождения, факультет, должность, стаж).
4.Создать базу (массив) из n персон, вывести полную информацию из базы на экран, отсортировав базу данных о персонах по дате рождения, а также организовать поиск персон, чей возраст попадает в заданный диапазон.
Задание 6
1.Создать абстрактный класс Goods с функциями, позволяющими вывести на экран информацию о товаре, а также определить, соответствует ли он сроку годности на текущую дату.
2.В абстрактном классе Goods реализовать метод CompareTo так, чтобы можно было отсортировать базу данных о товарах по их цене.
3.Создать производные классы: Product (название, цена, дата производства, срок годности), Party (название, цена, количество шт, дата производства, срок годности), Kit (название, цена, перечень продуктов).
4.Создать базу (массив) из n товаров, вывести полную информацию из базы на экран, отсортировав базу данных о товарах по их цене, а также организовать поиск просроченного товара (на момент текущей даты).
Задание 7
1.Создать абстрактный класс Goods с функциями, позволяющими вывести на экран информацию о товаре, а также определить, соответствует ли она искомому типу.
2.В абстрактном классе Goods реализовать метод CompareTo так, чтобы можно было отсортировать базу данных о товарах по возрасту детей, на которых он рассчитан.
3.Создать производные классы: Toy (название, цена, производитель, материал, возраст, на который рассчитана), Book (название, автор, цена, издательство, возраст, на который рассчитана), SportsEquipment (название, цена, производитель, возраст, на который рассчитан).
4.Создать базу (массив) из n товаров, вывести полную информацию из базы на экран, отсортировав базу данных о товарах по возрасту детей, на которых он рассчитан, а также организовать поиск товаров определенного типа.
Задание 8
29
1.Создать абстрактный класс TelephoneDirectory с функциями, позволяющими вывести на экран информацию о записях в телефонном справочнике, а также определить соответствие записи критерию поиска.
2.В абстрактном классе TelephoneDirectory реализовать метод CompareTo так, чтобы можно было отсортировать базу данных справочника по номеру телефона.
3.Создать производные классы: Persona (фамилия, адрес, номер телефона), Organization (название, адрес, телефон, факс, контактное лицо), Friend (фамилия, адрес, номер телефона, дата рождения).
4.Создать базу (массив) из n записей, вывести полную информацию из базы на экран, отсортировав базу данных справочника по номеру телефона, а также организовать поиск в базе по фамилии.
Задание 9
1.Создать абстрактный класс Client с функциями, позволяющими вывести на экран информацию о клиентах банка, а также определить соответствие клиента критерию поиска.
2.В абстрактном классе Client реализовать метод CompareTo так, чтобы можно было отсортировать базу данных о клиентах банка по дате открытия их счета.
3.Создать производные классы: Depositor (фамилия, дата открытия вклада, размер вклада, процент по вкладу), Credited (фамилия, дата выдачи кредита, размер кредита, процент по кредиту, остаток долга), Organization (название, дата открытия счета, номер счета, сумма на счету).
4.Создать базу (массив) из n клиентов, вывести полную информацию из базы на экран, отсортировав базу данных о клиентах банка по дате открытия их счета, а также организовать поиск клиентов, начавших сотрудничать с банком с заданной даты.
Задание 10
1.Создать абстрактный класс Software с методами, позволяющими вывести на экран информацию о программном обеспечении, а также определить соответствие возможности использования (на момент текущей даты).
2.В абстрактном классе Software реализовать метод CompareTo так, чтобы можно было отсортировать базу данных по названию ПО.
3.Создать производные классы: FreeSoftware (название, производитель), SharewareSoftware (название, производитель, дата установки, срок бесплатного использования), ProprietarySoftware (название, производитель, цена, дата установки, срок использования).
4.Создать базу (массив) из n видов программного обеспечения, вывести полную информацию из базы на экран, отсортировав базу данных по названию ПО, а также организовать поиск программного обеспечения, которое допустимо использовать на текущую дату.
30