|
Программирование >> Программирование с использованием ajax
public class MyClass { public class myNestedClass { public int nestedClassField; Для создания экземпляра myNestedClass за пределами myClass придется обязательно квалифицировать его имя, как показано ниже: MyClass.myNestedClass myObj = new MyClass.myNestedClass(); Однако выполнение подобной операции может оказаться и совершенно невозможным, в случае объявления вложенного класса с уровнем доступности private или другим уровнем, являющимся несовместимым с кодом на этапе выполнения такой операции создания экземпляра. Возможность создавать вложенные определения типов существует главным образом для того, чтобы позволять определять классы, являющиеся приватными по отношению к содержащему их классу, чтобы больше никакой другой код в пространстве имен не мог получать к ним доступ. Реализация интерфейсов Прежде чем продолжить, давайте подробнее остановимся на том, как определяются и реализуются интерфейсы. В предыдущей главе уже рассказывалось о том, что интерфейсы определяются подобно классам с использованием примерно такого кода: interface IMylnterface { Члены интерфейса. Члены интерфейсов тоже определяются подобно членам классов, но имеют несколько следующих важных отличий. а При определении членов интерфейсов не разрешается использовать модификаторы доступа (ни public, ни private, ни protected, ни internal); все члены интерфейсов неявно являются общедоступными. □ Члены интерфейсов не могут содержать тело кода. а В интерфейсах не могут определяться члены типа полей. □ Члены интерфейсов не могут определяться с использованием таких ключевых слов, как static, virtual, abstract или sealed. а в члены интерфейсов запрещено добавлять определения типов. Члены интерфейсов, однако, можно определять с использованием ключевого слова new при желании скрыть тех членов, которые наследуются от базовых интерфейсов: interface IMyBaselnterface { void DoSomethingО; interface IMyDerivedlnterfасе : IMyBaselnterface new void DoSomething (); Делается это тем же самым образом, как и сокрытие унаследованных членов класса. В тех свойствах, которые определяются в интерфейсах, может определяться как один, так и оба блока get и set в зависимости от того, какой уровень доступа обеспечивается к свойству: interface IMylnterface { int Mylnt { get; set; Здесь у int-свойства Mylnt имеется оба блока - и get, и set. В случае свойства с более ограниченным доступом какой-то из них может быть опущен. Данный синтаксис напоминает синтаксис автоматических свойств, но важно не забывать о том, что автоматические свойства определяются только для классов, а не для интерфейсов, и что в их случае обязательным является наличие обоих блоков get и set. В интерфейсах не указывается, как должны храниться данные свойств. В них, например, нельзя указывать те поля, которые могут использоваться для хранения данных свойств. И, наконец, последнее: интерфейсы, подобно классам, могут определяться в виде членов классов (но не в виде членов других экземпляров, поскольку интерфейсы не могут содержать определений типов). Реализация интерфейсов в классах в классе, который реализует интерфейс, должны обязательно содержаться реализации для всех членов этого интерфейсов, которые, в свою очередь, должны обязательно соответствовать указанным сигнатурам (а также указанным блокам get и set) и являться общедоступными (public): public interface IMylnterface { void DoSomething0; void DoSomethingElse (); public class MyClass : IMylnterface { public void DoSomething() public void DoSomethingElse () Члены интерфейсов допускается реализовать с использованием ключевого слова virtual или abstract, но не ключевого слова static или constant. Члены интерфейсов могут также реализоваться в базовых классах: public interface IMylnterface { void DoSomethingО; void DoSomethingElse0; public class MyBaseClass { public void DoSomething () public class MyDerivedClass : MyBaseClass, IMylnterface { public void DoSomethingElse () Наследование от базового класса, реализующего данный интерфейс, означает, что данный интерфейс также неявно поддерживается и производным классом. Например: public interface IMylnterface { void DoSomethingО; void DoSomethingElse0; public class MyBaseClass : IMylnterface { public virtual void DoSomething () public virtual void DoSomethingElse () public class MyDerivedClass : MyBaseClass { public override void DoSomething () Очевидно, что реализации в базовых классах лучше определять как виртуальные, чтобы в производных классах их можно было заменять, а не скрывать. Если бы пришлось скрывать член базового класса с использованием ключевого слова new, а не переопределять его, как было показано здесь, тогда метод IMylnterface. DoSomething всегда бы ссылался на ту версию, которая содержится в базовом классе, даже если бы доступ к производному классу осуществлялся через интерфейс. Явная реализация членов интерфейса Члены интерфейсов могут также реализоваться и явно самим классом. В случае применения такого подхода доступ к члену может осуществляться только через интерфейс, но не класс. Что касается членов, реализуемых неявно, которые демонстрировались в предыдущем разделе, то к ним доступ может осуществляться и тем, и другим способом. Например, если бы класс MyClass реализовал метод DoSomething интерфейса IMylnterface неявно, как это и было в предыдущем примере, тогда следующий код был бы допустимым: MyClass myObj = new MyClass (); myObj.DoSomething();
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |