- •Лекция 18. Перегрузка методов и операций в классах Перегрузка методов
- •Перегрузка операций
- •Перегрузка унарных операций
- •Пример перегрузки унарных операций на примере класса
- •Перегрузка бинарных операций
- •Public static тип_возвр_знач operator бинарная_операция (параметр1, параметр2),
- •Пример перегрузки бинарных операций на примере класса
- •Класс System.Object
- •Пример перегрузки операций сравнения с использованием стандартных методов класса Object
Пример перегрузки операций сравнения с использованием стандартных методов класса Object
namespace ConsoleApplication1
{
class Monster
{
public Monster(int сила, int умение, string имя)
{
this.сила = сила;
this.умение = умение;
this.имя = имя;
}
/* В данном методе сначала сравнивается экземпляр класса с "пустой" областью памяти и сравниваются два экземпляра класса на соотвествие типов и если одно из этих условий не выполняется возврщается False. Если же два экземпляра одного и того же класса «равны», то возвращается значение True, только в том случае, если все поля обоих классов совпадают.*/
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType()) return false;
Monster temp = (Monster)obj;
return (сила == temp.сила && умение == temp.умение && имя == temp.имя);
}
public override int GetHashCode()// Данный метод возвращает целое число, которое однозначно иденцифицирует экземпляр класса по имени.
{
return имя.GetHashCode();
}
public override string ToString()
{
return string.Format("Монстр {0} Сила {1} Умение {2}", имя, сила, умение);
}
string имя; //данные класса
int сила;
int умение;
} class Program
{
static void Main(string[] args)
{
Monster X = new Monster(100, 100, "Дима");
Monster Y = new Monster(100, 100, "Дима");
Monster Z = X; //Использование операции “присвоить”
if (X == Y) Console.WriteLine("Монстры равны!");
else Console.WriteLine("Монстры не равны"); // использование перегруженной операции сравнения на равенство
// В данном случаи монстр X и монстр Y не равны так как занимают в памяти разные адреса.Монстры X и Z будут равны.
if (X.Equals(Y)) Console.WriteLine("X эквивалентно Y"); //Монстры эквиваленты, так как имеют одинаковые значения полей
else Console.WriteLine("X не эквивалентно Y");
Console.WriteLine(X.GetType()); // Возвращается тип для экземпляра класса X. Возвратиться тип переменной X - ConsoleApplecation.Monster.
Console.ReadKey();
}
}
}
В методе Equals() сравниваются поля класса,
а в перегруженной операции «= =» области
памяти.
Перегрузку операций можно осуществить также с помощью стандартного интерфейса IComparable.
Если класс реализует интерфейс IComparable, его экземпляры можно сравнивать между собой по принципу больше или меньше. Можно использовать для этого операции отношения, перегрузив их. Операции должны перегружаться парами. Перегрузка операций обычно выполняется путем делегирования, то есть обращения к переопределенным методам CompareTo() и Equals().
Если класс реализует интерфейс IComparable, требуется переопределить метод Equals() и связанный с ним метод GetHashCode(). Оба метода унаследованы от базового класса object.
Рассмотрим предыдущий пример перегрузки операций отношений для класса Monster с использованием стандартного интерфейса IComparable.
В качестве критерия сравнения объектов по принципу больше или меньше выступает поле int сила, а при сравнении на равенство реализуется значимая семантика (то есть попарно сравниваются все поля объектов).
namespace ConsoleApplication1
{
class Monster : IComparable
{
public Monster(int сила, int умение, string имя)
{
this.сила = сила;
this.умение = умение;
this.имя = имя;
}
public void Passport()
{
Console.WriteLine("Монстр{0} \t сила ={1} умение={2}", имя, сила, умение);
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType()) return false;
Monster temp = (Monster)obj;
return (сила == temp.сила && умение == temp.умение && имя == temp.имя);
}
public override int GetHashCode()
{
return имя.GetHashCode();
}
//ПЕРЕГРУЗКА ОПЕРАЦИЙ СРАВНЕНИЯ С ИСПОЛЬЗОВАНИЕМ СТАНДАРТНОГО ИНТЕРФЕЙСА
public static bool operator ==(Monster a, Monster b)
{
return a.Equals(b);
}
/* ТО же самое с использованием метода CompareTo() интерфейса IComparable
public static bool operator ==(Monster a, Monster b)
{
return (a.CompareTo(b)==0);
}
*/
public static bool operator !=(Monster a, Monster b)
{
return !a.Equals(b);
}
public static bool operator <(Monster a, Monster b)
{
return (a.CompareTo(b)<0);
}
public static bool operator >(Monster a, Monster b)
{
return (a.CompareTo(b) > 0);
}
//Этот метод переопределяется ОБЯЗАТЕЛЬНО, так как это единственный метод //интерфейса IComparable
public int CompareTo(object obj)
{
Monster temp = (Monster)obj;
if (this.сила > temp.сила) return 1;
if (this.сила < temp.сила) return -1;
return 0;
}
string имя;
int сила, умение;
}
class Program
{
static void Main(string[] args)
{
Monster Вася = new Monster(50, 50, "Вася");
Вася.Passport();
Monster Петя = new Monster(100, 100, "Петя");
Петя.Passport();
if (Вася > Петя) Console.WriteLine("Вася сильнее Пети");
else if (Вася == Петя) Console.WriteLine("Монстры равны по силе");
else Console.WriteLine("Вася слабее Пети");
Console.ReadLine();
}
}
}
