При использовании интерфейсов может возникать неопределенность в случае, если в двух реализованных классом интерфейсах есть методы с одинаковыми именами и сигнатурами. Просмотрим, например, следующие версии интерфейсов lAccount и IState-ment. Обратите внимание, что в каждом из них есть метод Show (Показать).
_gc _interface lAccount
// сборщик мусора - IAccount
{
void Deposit(Decimal amount); // Депозит (Десятичное
// количество)
void Withdraw(Decimal amount); // Снять (Десятичное количество)
_property Decimal get_Balance(); // Десятичное число
void Show(); // Показать
};
_gc _interface IStatement // сборщик мусора - IStatement
{
_property int get_Transactions();
void Show(); // Показать
};
Как в подобном случае указать классу нужную реализацию метода? Такая задача решается благодаря использованию имени интерфейса вместе с именем реализуемого метода, как это продемонстрировано на примере программы Ambiguous (Неоднозначная программа). Версия метода Show (Показать), относящаяся к интерфейсу lAccount, выводит на экран информацию только о состоянии счета, а метод IStatement: : Show (Показать) выводит число сделок и баланс.
//Account.h
_gc class Account : public lAccount, public IStatement
// класс сборщика мусора Счет
{
private: // частный
Decimal decBalance; // Десятичное число
int nNumXact; public:
Account(Decimal decBalance) : nNumXact(O)
// Счет (Десятичное число decBalance)
{
this->decBalance = decBalance;
}
void Deposit(Decimal decAmount)
// Депозит (Десятичное число decAmount)
{
decBalance = decBalance + decAmount;
++nNumXact; } void Withdraw(Decimal decAmount) // Снять (Десятичное
// число decAmount)
{
decBalance = decBalance - decAmount;
++nNumXact;
}
_property Decimal get_Balance() // Десятичное число
{
return decBalance;
}
void lAccount::Show() // Показать
{
Console::WriteLine(
"balance = {0}", _box(decBalance)); // баланс
}
_property int get_Transactions()
{
return nNumXact;
}
void IStatement::Show() // Показать
{
Console::WriteLine(
"{0} transactions, balance = {!}", // сделки, баланс
_box(nNumXact),
_box(decBalance)) ;
}
};
Доступ к методам lAccount::Show (Показать) и IStatement:: Show (Показать) нельзя получить с использованием указателя на экземпляр класса. Доступ к этим методам возможен только с помощью указателя на интерфейс того типа, который явно указан в объявлениях методов. Приведенная программа демонстрирует, что метод lAccountShow можно вызвать только при использовании указателя на интерфейс lAccount, но не с помощью указателя на экземпляр класса Account (Счет). Попытка вызвать такой метод с помощью указателя на экземпляр класса является ошибкой и будет пресечена компилятором. Получая указатель на интерфейс IStatement, можно вызвать метод IStatement :: Show (Показать). Результат выполнения программы будет следующим:
О transactions, balance = 100
О transactions, balance = 100
balance = 115
2 transactions, balance = 115
Вот перевод:
О сделок, баланс = 100
О сделок, баланс = 100
баланс = 115
2 сделки, баланс = 115
Иногда и при отсутствии неопределенности желательно использовать явную реализацию интерфейсов для того, чтобы вынудить программу-клиента вызывать методы интерфейса с помощью указателя на интерфейс. Подобный подход дает уверенность в том, что в исходном коде программы-клиента явно указана принадлежность метода определенному интерфейсу, а не большому набору методов класса. Такой код легко адаптировать, чтобы применять для реализации других классов, использующих тот же интерфейс.