Обращение к функциональности базового класса
В VB.NET существует модификатор Protected, который автоматически предоставляет доступ из производных классов к соответствующему члену класса, будь то метод или переменная класса. Возникает искушение воспользоваться этим модификатором и объявить все поля базового класса с уровнем доступа Protected, чтобы производные классы могли легко и быстро работать с ними. Не поддавайтесь соблазну! Хороший стиль проектирования требует, чтобы модификатор Protected использовался только для методов, но не для переменных. В противном случае нарушается инкапсуляция и теряется возможность проверки данных там, где она должна происходить – в базовом классе. Как и в реальной жизни, здесь действует хороший принцип "доверяй, но проверяй".
Например, в исходное определение класса Employee входят свойства со следующими сигнатурами:
Public Readonly Property TheName() As String Public Readonly Property Salary() As Decimal
Таким образом, доступ к этим свойствам разрешен всем классам. Чтобы ограничить доступ к свойствам классами, производными от Employee, замените модификатор Public на Protected.
В табл. 5.1 перечислены различные модификаторы уровня доступа, присваиваемые членам классов в иерархии наследования.
Как было сказано выше, функции (но не поля!) с модификаторами Protected и Protected Friend распространены достаточно широко, поскольку они предотвращают доступ к защищенным членам со стороны внешнего кода.
При использовании Protected возникает весьма интересный подвох. К счастью, компилятор вовремя предупредит вас о возможных проблемах. Рассмотрим конкретный пример: допустим, у вас имеется класс GeekFest с методом Boast, который пытается обратиться к свойству Salary класса Programmer (что в конечном счете означает доступ к свойству Salагу базового класса Employee). Ниже приведен примерный вид программы:
Public Class GeekFest Private m_Programmers() As Programmer Sub New(ByVal Programmers() As Programmer) m_Programmers = Programmers End Sub Public Function Boast(ByVal aGeek As Programmer) As String Return "Hey my salary is " & aGeek.Salary End Function End Class
Таблица 5.1. Модификаторы уровня доступа при наследовании.
Модификатор | Описание |
---|---|
Friend | Доступ предоставляется только из текущей сборки |
Private | Доступ предоставляется только объектам базового класса |
Protected | Доступ ограничивается объектами базового класса и объектами любых производных классов |
Protected Friend | Доступ предоставляется только из текущей сборки или из классов, производных отданного базового класса (может рассматриваться как комбинация модификаторов Protected и Friend) |
Public | Доступ к члену класса предоставляется всем, кто имеет доступ к классу в соответствии с модификатором самого класса |
Также допустим, что в класс Employee входит свойство Salагу, доступное только для чтения и помеченное модификатором Protected вместо Public:
Protected Readonly Property Salary() As Decimal Get Return MyClass.m_Salary End Get End Property
В результате компилятор выдает сообщение об ошибке:
C:\vb net book\chapter 5\Examplel\Examplel\Moduleld.vb(19): 'Examplel. Modulel.Employee. Protected Readonly Property Salary() As Decimal' is Protected.and is not accessible in this context.
Хотя класс Programmer обладает доступом к защищенному свойству Salary в своем коде, объекты Programmer не имеют доступа к этому методу за пределами кода класса Programmer. Подведем итог:
Обращение к Protected-методам базового класса возможно только из объектов производного класса, но не из внешних ссылок на эти объекты за пределами производного класса.