Обращение к функциональности базового класса
Обращение к функциональности базового класса
В VB .NET существует модификатор Protected, который автоматически предоставляет доступ из производных классов к соответствующему члену класса, будь то метод или переменная класса. Возникает искушение воспользоваться этим модификатором и объявить все поля базового класса с уровнем доступа Protected, чтобы производные классы могли легко и быстро работать с ними. Не поддавайтесь соблазну! Хороший стиль проектирования требует, чтобы модификатор Protected использовался только для методов, но не для переменных. В противном случае нарушается инкапсуляция и теряется возможность проверки данных там, где она должна происходить — в базовом классе. Как и в реальной жизни, здесь действует хороший принцип «доверяй, но проверяй».
Например, в исходное определение класса Employee входят свойства со следующими сигнатурами:
Public Readonly Property TheName() As String
Public Readonly Property Salary() As Decimal
Таким образом, доступ к этим свойствам разрешен всем классам. Чтобы ограничить доступ к свойствам классами, производными от Empl oyee, замените модификатор Publ ic на Protected.
В табл. 5.1 перечислены различные модификаторы уровня доступа, присваиваемые членам классов в иерархии наследования.
Как было сказано выше, функции (но не поля!) с модификаторами Protected и Protected Friend распространены достаточно широко, поскольку они предотвращают доступ к защищенным членам со стороны внешнего кода.
При использовании Protected возникает весьма интересный подвох. К счастью, компилятор вовремя предупредит вас о возможных проблемах. Рассмотрим конкретный пример: допустим, у вас имеется класс GeekFest с методом Boast, который пытается обратиться к свойству Salary класса Programmer (что в конечном счете означает доступ к свойству Sal агу базового класса Empl oyee). Ниже приведен примерный вид программы:
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 | Доступ к члену класса предоставляется всем, кто имеет доступ к классу в соответствии с модификатором самого класса | ||
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-методам базового класса возможно только из объектов производного класса, но не из внешних ссылок на эти объекты за пределами производного класса.