Программирование с использованием интерфейсов
Использование интерфейсов
Когда известно, что некоторый класс поддерживает определенный интерфейс, его методы можно вызывать с помощью указателя на экземпляр класса. Если же неизвестно, реализован ли интерфейс классом, можно попытаться выполнить приведение указателя на класс к указателю на интерфейс. И если класс не поддерживает данный интерфейс, при такой попытке возникнет исключение. В следующем примере, взятом из файла Smalllnterfасе.h, демонстрируется именно такой способ проверки.
try // попытка { IBasicAccount *pifc2 = dynamic_cast<IBasicAccount *>(pacc2); pifc2 › Deposit(25); // Депозит Console::WriteLine( "balance = {0}", _box(pifc2 › Balance)); // Баланс } catch (NullReferenceException *pe) { Console::WriteLine( "IBasicAccount is not supported"); // IBasicAccount // не поддерживается Console::WriteLine(pe › Message); // Сообщение } }
В программе Small Interface используются два почти одинаковых класса. Класс Account (Счет) поддерживает интерфейс IBasicAccount, а второй класс, NoAccount его не поддерживает. Оба класса имеют идентичные наборы методов и свойств. Приведем полностью содержимое файлов Smalllnterfасе.срр и Smalllnterfасе.h. Заметим, что в этой программе делаются попытки привести указатели на экземпляры классов Account (Счет) и NoAccount к указателю на интерфейс IBasicAccount.
//Smalllnterfасе.срр fusing <mscorlib.dll> using namespace System; // использование пространства имен Система; #include "Account.h" #include "NoAccount.h" #include "Smalllnterface.h" void main() // главный { Smalllnterface::Main(); // Главный } //Smalllnterface.h _gc class Smalllnterface // класс сборщика мусора Smalllnterface { public: static void Main() // Главный { Account *pacc – new Account(100); // новый Счет // Использовать ссылку на класс Console::WriteLine( "balance = {0}", _box(pacc › Balance)); // Баланс pacc › Deposit(25); // Депозит Console::WriteLine( "balance = {0}", _box(pacc › Balance)); // Баланс // Использовать ссылку на интерфейс IBasicAccount *pifc = dynamic_cast<IBasicAccount *>(pacc); pifc › Deposit(25); // Депозит Console::WriteLine( "balance = {0}", _box(pifc › Balance)); // Баланс // Теперь попробовать с классом, // не реализующим IBasicAccount NoAccount *pacc2 = new NoAccount(500); // Использовать ссылку на класс Console::WriteLine( "balance = {0}", _box(pacc2 › Balance)); // Баланс pacc2 › Deposit(25); // Депозит Console::WriteLine( "balance = {0}", _box(pacc2 › Balance)); // Баланс // Испробовать указатель на интерфейс try // попытка { IBasicAccount *piba= dynamic_cast<IBasicAccount *>(pacc2); piba › Deposit(25); // Депозит Console::WriteLine( "balance = {0}", _box(piba › Balance)); // Баланс } catch (NullReferenceException *pe) { Console::WriteLine( "IBasicAccount is not supported"); // IBasicAccount //не поддерживается Console::WriteLine(pe › Message); // Сообщение } } };