Перегрузка операторов позволяет определить воздействие операторов на объекты, т.е., благодаря перегрузке операторов, мы можем применять их к объектам. В принципе, перегрузка оператора осуществляется специальным методом. Метод перегруженного
операторов должен объявляться как public static. Операторы бывают унарные и бинарные. Унарные операторы работают с одним операндом, а бинарные - с двумя. Для указания перегрузки операторов используется ключевое слово operator. В зависимости от количества операндов, различают две общие формы операторных методов. Вот и они:
public static возвращаемый_тип operator #(тип_операнда операнд)
{
//тело метода унарного оператора
}
public static возвращаемый_тип operator #(тип_операнда1 операнд1, тип_операнда2 операнд2)
{
//тело метода бинарного оператора
}
Теперь некоторые ограничения на перегрузку операторов:
- приоритет операторов не меняется (в C# приоритет операторов можно считать таким же, как и в C/C++);
- нельзя менять определенное в языке для конкретного оператора количество операндов;
- тело метода перегружаемого оператора должно определять действия оператора, по отношению к объекту/объектам текущего класса.
- операторы сравнения (кроме равенства) надо определять по два, т.е., если есть '>', то должно быть и '<';
- нельзя перегружать операторы сравнения
И, наконец, перегрузим несколько операторов для нашего класса Matrix. В нем я буду использовать условный оператор if(выражение){блок1;}else{блок2;}. Для тех, кто с ним не знаком, объясняю... Если выражение в круглых скобках принимает значение истины, то выполняется блок1, иначе - блок2, следующий за else. Все просто!
//Этуот пример можно было бы сделать красивее,
//с динамическим распределением, но некоторым
//это пока будет сложно
using Sc=System.Console;
class Matrix// класс матрицы
{
//-Объявим-закрытый-член-класса----------
//-Массив-10x10-целочисленных-переменных-
//-Элементов-матрицы---------------------
int[,] element=new int[4,4];
//----Конструктор-по-умолчанию---------
public Matrix()
{
int i,j;
//цикл для прохода по строкам
for(i=0;i<4;i++)
{ //цикл для прохода по элементам строки
for(j=0;j<4;j++)
{ //установка в 0 каждого элемента
element[i,j]=0;
}
}
}
//-теперь-определим-методы-присваивания-и---
//-получения-значения-определенному-элементу-
public void SetValue(int line,int row,int value)
{
element[line,row]=value;
}
public int GetValue(int line,int row)
{
return element[line,row];
}
//-определим-перегруженный-метод-вывода-
public void Print()//вывод всей матрицы
{
int i,j;//переменные для циклов
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
Sc.Write(" "+GetValue(i,j));
}
Sc.WriteLine();
}Sc.ReadLine();
}
public void Print(int line)//вывод строки
{
int j;
for(j=0;j<4;j++)
{
Sc.Write(" "+GetValue(line,j));
}
Sc.WriteLine();
Sc.ReadLine();
}
public void Print(int line,int row)//вывод элемента
{
Sc.WriteLine("Element["+line+","+row+"]="+GetValue(line,row));
}
//-и-наконец-метод-ввода-всех-элементов-
public void Scan()
{
int i,j,ii;
for(i=0;i<4;i++)
{
string str1;
ii=i+1;
Sc.WriteLine("Enter string #"+ii);
for(j=0;j<4;j++)
{
Sc.Write("Enter value for element["+i+","+j+"](then press Enter)=>");
str1=Sc.ReadLine();
element[i,j]=int.Parse(str1);
}
Sc.WriteLine();
}
}
public int Sum()//счет суммы всех элементов
{
int sum=0;
int i,j;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++) sum=sum+element[i,j];
//или sum+=element[i,j];
}
return sum;
}
//А вот и они - операторы
public static Matrix operator ++(Matrix m)
{//унарный оператор инкремента
int i,j;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++) m.element[i,j]++;
}
return m;
}
public static Matrix operator +(Matrix m1,Matrix m2)
{//бинарный оператор сложения
Matrix mresult=new Matrix();
int i,j;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++) mresult.element[i,j]=m1.element[i,j]+m2.element[i,j];
}
return mresult;
}
//операторы сравнения возвращают значения
//типа bool (1 или 0)
//часто используются в выражениях
//условных операторов
public static bool operator >(Matrix m1,Matrix m2)
{
if(m1.Sum()>m2.Sum()) return true;
else return false;
}
public static bool operator <(Matrix m1,Matrix m2)
{
if(m1.Sum()<m2.Sum()) return true;
else return false;
}
}
class Application
{
public static void Main()
{
Matrix matrix1=new Matrix();
Matrix matrix2=new Matrix();
Matrix matrix3=new Matrix();
Sc.WriteLine("Input 1st matrix:");
matrix1.Scan();matrix1++;
Sc.WriteLine("1st matrix incremented:");
matrix1.Print();
Sc.WriteLine("input 2nd matrix:");
matrix2.Scan();
matrix3=matrix1+matrix2;
Sc.WriteLine("matrix1 + matrix2 is");
matrix3.Print();
if(matrix3>matrix2) Sc.WriteLine("matrix3 is bigger");
else Sc.WriteLine("matrix3 is not bigger");
Sc.ReadLine();
}
}
Чтобы перегрузить операторы '==' и '!=' необходимо переопределить методы Equals() и GetHashCode() базового класса Object (или типа object). Для полного счастья, сделаем уже и это. Но, для начала, я расскажу немного о упаковке/распаковке. Все классы автоматически наследуют фундаментальный класс Object. Следовательно, любой тип или класс можно привести к типу object. Возможна и обратная процедура. Приведение объекта к объекту базового типа
object и называется упаковкой. Распаковка - это обратная процедура. В следующем примере мы воспользуемся распаковкой в переопределении метода Equals(object o). Критерий равенства матриц - равенство сумм всех элементов обеих матриц. Просто добавляем следующие методы в наш класс
Matrix...
public override int GetHashCode()
{
return 100;
}
public override bool Equals(object o)
{
//unpack it now
Matrix matr=(Matrix)o;
if(Sum()==matr.Sum()) return true;
else return false;
}
public static bool operator ==(Matrix m1,Matrix m2)
{
if(m1.Sum()==m2.Sum()) return true;
else return false;
}
public static bool operator !=(Matrix m1,Matrix m2)
{
if(m1.Sum()!=m2.Sum()) return true;
else return false;
}
И следующие строки в конец метода Main()...
if(matrix1==matrix2) Sc.WriteLine("matrix1=matrix2");
else Sc.WriteLine("matrix1!=matrix2");
Sc.ReadLine();
Далее комментировать эту прогу я не вижу смысла. Командная строка, csc имя_файла & GO! Ну, создавать классы умеем, интерфейсы - умеем, умеем наследовать, умеем перегружать операторы и методы, умеем пользоваться объектами, создавать новые типы данных, если вы, конечно, прочитали все мои статьи. Можно, сказать, что теперь и ты знаешь основы объектно-ориентированного программирования, Нео!