Принципы объектно-ориентированного программирования

         

Синтаксис и пример



Синтаксис и пример

Итак, перегрузка оператора — это разновидность вызова метода. Для переопределения оператора применяется такой шаблон (здесь on — перегружаемый оператор):

public static возвращаемое_значение operator"/? (объект! [, объект2\) При перегрузке операторов учитывайте следующие факты.

  • Все методы, представляющие перегружаемые операторы, должны быть определены как

    public и static.
  • Формально возвращаемое^значение может быть любого типа. Однако общая практика — возвращать тип, для которого определяется метод (кроме операторов true и false — они должны всегда возвращать булево значение).
  • Число передаваемых аргументов (объект!, объект!) зависит от типа перегружаемого оператора. Для унарных (т. е. с одним операндом) операторов должен указываться один аргумент. Для перегрузки бинарного (т. е. с двумя операндами) оператора передаются два аргумента.
  • В случае унарных операторов аргумент этого метода должен быть того же типа, что и включенный в него класс или структура. Иначе говоря, если вы переопределяете унарный оператор "!" для класса Foo,

1 В английском языке по звучанию напоминает "синтетический сахар". — Прим. перев.

этот метод в качестве аргумента должен принимать только переменные типа Foo.

  • Если перегружается бинарный оператор, тип первого аргумента должен совпадать с типом вложенного класса, а второй может быть любого типа.

В псевдокоде предыдущего раздела я использовал оператор += с классом Invoice. По причинам, которые скоро будут вам понятны, такие составные операторы на самом деле перегрузить нельзя. Переопределить можно только "базовый" оператор, в данном случае +. Вот синтаксис определения метода operator+ метода Invoice:

public static Invoice operator+ (Invoice invoice!, Invoice invoice2) <

// Создаем новый объект Invoice.

// Добавляем необходимое содержимое из

// invoice! в новый объект Invoice.

// Добавляем необходимое содержимое из

// invoice2 в новый объект Invoice.

// Возвращаем новый объект Invoice. >

Теперь рассмотрим пример, более приближенный к действительности, с двумя классами: Invoice и InvoiceDetailLine. Invoice имеет член-переменную типа Array List, который представляет совокупность позиций из всех счетов. Чтобы можно было суммировать позиции из нескольких счетов, я перегрузил оператор + (см. метод operator+). Метод Invoice.оре-rator+ создает новый объект Invoice и проходит по массивам обоих объектов, добавляя каждую позицию к новому объекту Invoice. Затем этот объект возвращается вызывающему методу. Разумеется, в реальном приложении все будет значительно сложней, а здесь я лишь.показываю, как на самом деле могут перегружаться операторы.

using System;

using System.Collections;

class InvoiceDetailLine {

double lineTotal; public double LineTotal {

get {

return this.lineTotal;

} }

public InvoiceDetailLine(double LineTotal) {

this.lineTotal = LineTotal; } }

class Invoice {

public ArrayList DetailLines;

public InvoiceO {

DetailLines = new ArrayListQ; }

public void Printlnvoice() {

Console.WriteLine("\nn,03vmKfl Nbr\tBcero");

int i = 1;

double total = 0;

foreach(InvoiceDetailLine detailLine in DetailLines)

{

Console.WriteLine("{0}\t\t{1}", i++, detailLine.LineTotal);

total += detailLine.LineTotal; }

Console.WriteLine("=====\t\t==="); Console.WriteLine("Bcero\t\t{1}", i++, total); }

public static Invoice operator* (Invoice invoicel,

Invoice invoice2) {

Invoice returnlnvoice = new InvoiceO;

foreach (InvoiceDetailLine detailLine in

invoicel.DetailLines) {

returnlnvoice.DetailLines.Add(detailLine); >

foreach (InvoiceDetailLine detailLine in

invoice2.DetailLines) {

returnlnvoice.DetailLines.Add(detailLine); }

return returnlnvoice; } }

class InvoiceAddApp {

public static void Main() {

Invoice 11 = new InvoiceO; for (int i = 0; i < 2; i++) {

11.DetailLines.Add(new InvoiceDetailLine(i + 1)); }

Invoice i2 = new InvoiceO; for (int i = 0; i < 2; i++) <

12.DetailLines.Add(new InvoiceDetailLine(i + 1)); }

Invoice summarylnvoice = it + 12; summarylnvoice.PrintlnvoiceO; } }



Содержание раздела