Главная arrow Язык программирования C# arrow C# Полное руководство Герберт Шилдт arrow Выполнение операций со встроенными в C# типами данных C# Полное руководство Герберт Шилдт

Выполнение операций со встроенными в C# типами данных C# Полное руководство Герберт Шилдт

Для любого заданного класса и оператора имеется также возможность перегрузить сам операторный метод. Это, в частности, требуется для того, чтобы разрешить операции с типом класса и другими типами данных, в том числе и встроенными. Вновь обратимся к классу ThreeD. На примере этого класса ранее было показано, как оператор + перегружается для сложения координат одного объекта типа ThreeD с координатами другого. Но это далеко не единственный способ определения операции сложения для класса ThreeD. Так, было бы не менее полезно прибавить целое значение к каждой координате объекта типа ThreeD. Подобная операция пригодилась бы для переноса осей координат. Но для ее выполнения придется перегрузить оператор + еще раз, как показано ниже.

// Перегрузить бинарный оператор + для сложения объекта
// типа ThreeD и целого значения типа int.
public static ThreeD operator +(ThreeD op1, int op2)
{
   ThreeD result = new ThreeD ();
   result.x = op1.x + op2;
   result,у = op1.y + op2;
   result.z = op1.z + op2;

   return result;
}

Как видите, второй параметр операторного метода имеет тип int. Следовательно, в этом методе разрешается сложение целого значения с каждым полем объекта типа ThreeD. Такая операция вполне допустима, потому что, как пояснялось выше, при перегрузке бинарного оператора один из его операндов должен быть того же типа, что и класс, для которого этот оператор перегружается. Но у второго операнда этого оператора может быть любой другой тип.
Ниже приведен вариант класса ThreeD с двумя перегружаемыми методами оператора +.

// Перегрузить бинарный оператор + дважды: один раз -
// для сложения объектов класса ThreeD, а другой раз —
// для сложения объекта типа ThreeD и целого значения
// типа int.

using System;

// Класс для хранения трехмерных координат,
class ThreeD {
   int х, у, z; // трехмерные координаты
   public ThreeD () { х = у = z = 0; }
   public ThreeD (int i, int j, int k) { x = i; у = j; z = k; }

   // Перегрузить бинарный оператор + для сложения
   // объектов класса ThreeD.
   public static ThreeD operator + (ThreeD op1, ThreeD op2)
   {
      ThreeD result = new ThreeD();

      /* Сложить координаты двух точек и возвратить
          результат. */
      result.х = op1.x + ор2.х;
      result.у = op1.y + ор2.у;
      result.z = op1.z + op2.z;

      return result;
   }

   // Перегрузить бинарный оператор + для сложения
   // объекта типа ThreeD и целого значения типа int.
   public static ThreeD operator + (ThreeD op1, int op2)
   {
      ThreeD result = new ThreeDO;

      result.x = op1.x + op2;
      result.у = op1.у + op2;
      result.z = op1.z + op2;

      return result;
   }

   // Вывести координаты X, Y, Z.
   public void Show()
   {
      Console .WriteLine (x + ", " + у + ", " + z);
   }
}

class ThreeDDemo {
   static void Main() {
      ThreeD a = new ThreeD (1, 2, 3) ;
      ThreeD b = new ThreeD(10, 10, 10);
      ThreeD с = new ThreeD();
      Console.Write("Координаты точки a: ");
      a.Show();
      Console.WriteLine() ;
      Console.Write("Координаты точки b: ");
      b.Show();
      Console.WriteLine() ;

      с = a + b; // сложить объекты класса ThreeD
      Console.Write("Результат сложения a + b: ");
      c.Show();
      Console.WriteLine();

      c = b + 10; // сложить объект типа ThreeD и целое
                          // значение типа int
      Console.Write("Результат сложения b + 10: ");
      с.Show ();
   }
}


При выполнении этого кода получается следующий результат:
   Координаты точки а: 1, 2, 3
   Координаты точки b: 10, 10, 10
   Результат сложения а + b: 11, 12, 13
   Результат сложения b + 10: 20, 20, 20

Как подтверждает приведенный выше результат, когда оператор + применяется к двум объектам класса ThreeD, то складываются их координаты. А когда он применяется к объекту типа ThreeD и целому значению, то координаты этого объекта увеличиваются на заданное целое значение.
Продемонстрированная выше перегрузка оператора +, безусловно, расширяет полезные функции класса ThreeD, тем не менее, она делает это не до конца. И вот почему. Метод operator+ (ThreeD, int) позволяет выполнять операции, подобные следующей:
   ob1 = оb2 + 10;
Но, к сожалению, он не позволяет выполнять операции, аналогичные следующей:
   ob1 = 10 + оb2;
Дело в том, что второй целочисленный аргумент данного метода обозначает правый операнд бинарного оператор +, но в приведенной выше строке кода целочисленный аргумент указывается слева. Для того чтобы разрешить выполнение такой операции сложения, придется перегрузить оператор + еще раз. В этом случае первый параметр операторного метода должен иметь тип int, а второй параметр — тип ThreeD. Таким образом, в одном варианте метода operator+ () выполняется сложение объекта типа ThreeD и целого значения, а во втором — сложение целого значения и объекта типа ThreeD. Благодаря такой перегрузке оператора + (или любого другого бинарного оператора) допускается появление встроенного типа данных как с левой, так и с правой стороны данного оператора. Ниже приведен еще один вариант класса ThreeD, в котором бинарный оператор + перегружается описанным выше образом.

   // Перегрузить бинарный оператор + трижды: один раз —
   // для сложения объектов класса ThreeD, второй раз —
   // для сложения объекта типа ThreeD и целого значения
   // типа int, а третий раз — для сложения целого значения
   // типа int и объекта типа ThreeD.

   using System;

   // Класс для хранения трехмерных координат.
   class ThreeD {
      int х, у, z; // трехмерные координаты
      public ThreeD() { х = у = z = 0; }
      public ThreeD (int i, int j, int k) { x = i; у = j; z = k; }

      // Перегрузить бинарный оператор + для сложения
      // объектов класса ThreeD.
      public static ThreeD operator +(ThreeD op1, ThreeD op2)
      {
         ThreeD result = new ThreeD();

         /* Сложить координаты двух точек и возвратить
         результат. */
     result.х = op1.x + ор2.х;
     result.у = op1.y + ор2.у;
     result.z = op1.z + op2.z;

         return result;
      }
      
      // Перегрузить бинарный оператор + для сложения
      // объекта типа ThreeD и целого значения типа int.
      public static ThreeD operator + (ThreeD op1, int op2)
      {
         ThreeD result = new ThreeD();

      result.x = op1.x + op2;
      result.у = op1.у + op2;
      result.z = op1.z + op2;

      return result;
   }

   // Перегрузить бинарный оператор + для сложения
   // целого значения типа int и объекта типа ThreeD.
   public static ThreeD operator +(int op1, ThreeD op2)
   {
      ThreeD result = new ThreeD();

      result, x = op2.x + op1;
      result, у = op2.y + op1;
      result, z = op2.z + op1;

      return result;
   }

   // Вывести координаты X, Y, Z.
   public void Show()
   {
   Console .WriteLine (x + ", " + у + ", " + z);
   }
}

class ThreeDDemo {
   static void Main() {
      ThreeD a = new ThreeD (1, 2, 3) ;
      ThreeD b = new ThreeD (10, 10, 10);
      ThreeD с = new ThreeDO;
      Console.Write("Координаты точки a: ");
      a.Show();
      Console.WriteLine ();
      Console.Write("Координаты точки b: ");
      b.Show();
      Console.WriteLine ();
      
      с = a + b; // сложить объекты класса
      ThreeD Console.Write("Результат сложения a + b: ");
      c.Show();
      Console.WriteLine ();

      c = b + 10; // сложить объект типа ThreeD и целое
                          // значение типа int
      Console.Write("Результат сложения b + 10: ");
      с.Show();
      Console.WriteLine ();
      
      с = 15 + b; // сложить целое значение типа int и
                         // объект типа ThreeD
      Console.Write("Результат сложения 15 + b: ");
      с.Show () ;
   }
}


Выполнение этого кода дает следующий результат:
   Координаты точки а: 1, 2, 3
   Координаты точки b: 10, 10, 10
   Результат сложения а + b: 11, 12, 13
   Результат сложения b + 10: 20, 20, 20
   Результат сложения 15 + b: 25, 25, 25