Читаем Интернет-журнал "Домашняя лаборатория", 2007 №9 полностью

public class IntCalc: Calc

{

    public override int Add(int a, int b) { return (a + b);}

    public override int Sub (int a, int b) { return (a — b);}

    public override int Mult(int a, int b) { return (a * b);}

    public override int Div(int a, int b) { return (a / b); }

}

public class DoubleCalc: Calc

{

    public override double Add(double a, double b)

        {return (a + b);}

    public override double Sub(double a, double b)

        {return (a — b);}

    public override double Mult(double a, double b)

        {return (a * b);}

    public override double Div(double a, double b)

        {return (a / b);}

}

public class StringCalc: Calc

{

    public override string Add(string a, string b)

        {return (a + b);}

    public override string Sub(string a, string b)

        {return (a);}

    public override string Mult(string a, string b)

        {return (a);}

    public override string Div (string a, string b)

        {return (a);}

}

Здесь определяются три разных калькулятора: один — над целочисленными данными, другой — над данными с плавающей точкой, третий — над строковыми данными. В последнем случае определена, по сути, только операция сложения строк (конкатенации).

Теперь нам нужно ввести изменения в ранее созданный класс OneLinkList. Обратите внимание на важный технологический принцип работы с объектными системами. Пусть уже есть нормально работающий класс с нормально работающими клиентами класса. Не следует изменять этот класс. Класс закрыт для изменений. Используйте наследование и открывайте класс-потомок, в который и вносите изменения, учитывающие добавляемую специфику класса. Принцип "Закрыт — Открыт" является одним из важнейших принципов построения программных систем в объектном стиле.

В полном соответствии с этим принципом построим класс SumList — потомок класса OneLinkList. То, что родительский класс является универсальным, ничуть не мешает строить потомка класса, сохраняющего универсальный характер родителя.

public class SumList: OneLinkList where К:

    IComparable

{

    Calc calc;

    T s um;

    public SumList(Calc calc)

    { this.calc = calc; sum = default(T); }

    public new void add(K key, T item)

    {

       Node newnode = new Node();

       if (first == null)

       {

           first = newnode; cursor = newnode;

           newnode.key = key; newnode.item = item;

           sum = calc.Add(sum, item);

       }

       else

       {

           newnode.next = cursor.next; cursor.next = newnode;

           newnode.key = key; newnode.item = item;

           sum = calc.Add(sum, item);

        }

    }

    public T Sum()

    {return (sum); }

}//SumList

У класса добавилось поле sum, задающее сумму хранимых элементов, и поле calc — калькулятор, выполняющий вычисления. Метод add, объявленный в классе с модификатором new, скрывает родительский метод add, задавая собственную реализацию этого метода. Родительский метод можно было бы определить как виртуальный, переопределив его у потомка, но я не стал трогать код родительского класса. К классу добавился еще один запрос, возвращающий значение поля sum.

Некоторые изменения в уже существующем проекте пришлось-таки сделать, изменив статус доступа у полей. А все потому, что в целях экономии текста кода я не стал закрывать поля и вводить, как положено, открытые процедуры-свойства для закрытых полей.

Проведем теперь эксперименты с новыми вариантами списков, допускающих суммирование элементов:

Перейти на страницу:

Похожие книги