Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
26
Добавлен:
29.02.2016
Размер:
69.59 Кб
Скачать

Производные интерфейсы

Интерфейсы могут быть унаследованы друг от друга  точно так же, как классы. Эта кон­цепция иллюстрируется ниже определением нового интерфейса ITransferBankAccount, который обладает теми же возможностями, что и IBankAccount, но также определяет метод для перевода денег непосредственно на другой счет:

namespace Wrox.ProCSharp

{

public interface ITransferBankAccount: IBankAccount

{

bool TransferTo(IBankAccount destination, decimal amount);

}

)

Поскольку ITransferBankAccount наследуется от IBankAccount, наряду с собствен­ными методами он получает все методы-члены IBankAccount. Это значит, что любой класс, реализующий (унаследованный от) ITransferBankAccount, должен реализовать все методы IBankAccount наряду с новым методом TransferTo(), определенным в ITransferBankAccount. Отсутствие реализации любого из этих методов приведет к ошиб­ке компиляции.

Обратите внимание на то, что метод TransferTo() использует ссылку на интерфейс IBankAccount для указания целевого счета. Это иллюстрирует полезность интерфейсов. При реализации и последующем вызове метода вам не обязательно знать что-либо о типе объекта, которому переводятся деньги. Все, что необходимо знать  это то, что объект реализует интерфейс IBankAccount.

Чтобы проиллюстрировать применение ITransferBankAccount, предположим, что Планетарный Банк Юпитера также предлагает текущий счет (Current Account). Большая часть реализации класса CurrentAccount идентична реализациям SaverAccount и GoldAccount (опять же, это только для простоты примера  в реальности все далеко не так). Поэтому в следующем фрагменте выделена отличающаяся часть:

public class CurrentAccount: ITransferBankAccount

{

private decimal balance; public void Payln(decimal amount)

{

balance += amount;

}

public bool Withdraw(decimal amount)

{

if (balance >= amount)

{

balance -= amount;

return true;

}

Console.WriteLine("Попытка перевода денег не удалась.");

return false;

}

public decimal Balance

{

get

{

return balance;

}

}

public bool TransferTo(IBankAccount destination, decimal amount)

{

bool result;

result = Withdraw (amount) ;

if (result)

{

destination.Payln(amount);

}

return result;

}

public override string ToString()

{

return String.Format(

"Текущий счет в Банке Юпитера: Баланс = {0,6:С}", balance);

}

}

Класс можно протестировать с помощью следующего кода:

static void Main()

{

IBankAccount venusAccount = new SaverAccount ();

ITransferBankAccount jupiterAccount = new CurrentAccount();

venusAccount.Payln(200); jupiterAccount.Payln(500);

jupiterAccount.TransferTo(venusAccount, 100);

Console.WriteLine(venusAccount.ToString0) ;

Console.WriteLine(jupiterAccount.ToString() ) ;

)

Этот код (CurrentAccount.cs) генерирует следующий вывод, по которому можно убе­диться в том, что перевод правильной денежной суммы выполнен:

С:> CurrentAccount

Сберегательный Банк Венеры: Баланс = £300.00

Текущий счет в Банке Юпитера: Баланс = £400.00

Итоги

В данном разделе было показано, как кодировать наследование в С#. Вы увидели, что C# предлагает богатую поддержку наследования множества интерфейсов и одной реа­лизации. Также вы узнали о том, что в C# имеется множество полезных синтаксических конструкций, предназначенных для обеспечения большей устойчивости кода. Среди этих конструкций ключевое слово override, указывающее, когда функция должна переопреде­лять базовую функцию, ключевое слово new, указывающее, что функция скрывает базовую функцию, а также жесткие правила инициализации конструкторов, предназначенные для обеспечения их устойчивого взаимодействия.

Соседние файлы в папке 04 Наследование