Модификаторы доступа
Часть раздела Объектно-ориентированное программирование путешествия по C# на Coddy — урок 31 из 70.
Модификаторы доступа управляют тем, кто может видеть и использовать члены вашего класса. Они являются основой инкапсуляции — одного из основных принципов ООП. Ограничивая доступ, вы защищаете свои данные и создаете четкие границы в своем коде.
C# предоставляет четыре основных модификатора доступа:
public class BankAccount
{
public string AccountHolder; // Доступно отовсюду
private decimal balance; // Только внутри этого класса
protected string accountType; // Этот класс и производные классы
internal int branchCode; // В пределах той же сборки
}Члены public доступны из любого кода.
Члены private могут быть доступны только внутри того же класса — это самый строгий уровень доступа и значение по умолчанию для членов класса.
protected разрешает доступ из самого класса и любого класса, который наследуется от него.
internal ограничивает доступ к коду внутри той же сборки (проекта).
Если модификатор не указан, члены класса по умолчанию являются private:
class Example
{
int secret; // private по умолчанию
}Выбор правильного уровня доступа заключается в том, чтобы открывать только то, что необходимо. Начните с private и увеличивайте видимость только тогда, когда для этого есть веская причина. Это предотвращает зависимость другого кода от деталей реализации, которые вы, возможно, захотите изменить позже.
Задание
ЛегкоДавайте создадим безопасную систему профилей пользователей, которая демонстрирует, как модификаторы доступа защищают конфиденциальные данные, открывая только то, что необходимо. Вы создадите класс, в котором различные фрагменты информации имеют разные уровни видимости в зависимости от того, кто должен иметь к ним доступ.
Вы организуете свой код в трех файлах:
UserProfile.cs: Создайте классUserProfileв пространстве именSecurity, который управляет информацией о пользователе с соответствующими уровнями доступа. Профиль должен иметь:publicсвойствоUsername(string) — имя пользователя может видеть кто угодноprivateполеpassword(string) — доступ к нему должен иметь только сам классprotectedполеemail(string) — доступ к нему может иметь класс и его производные классыinternalполеuserId(int) — доступно внутри той же сборки
publicметод с именемGetPublicInfo(), который возвращает"User: {Username}". Добавьте еще одинpublicметод с именемValidatePassword(string input), который возвращаетtrue, если ввод совпадает с приватным паролем, иfalseв противном случае.AdminProfile.cs: Создайте классAdminProfileв пространстве именSecurity, который наследуется отUserProfile. Этот класс демонстрирует, какprotectedчлены становятся доступными в производных классах. Конструктор должен принимать те же четыре параметра и передавать их в базовый конструктор. Добавьтеpublicметод с именемGetAdminInfo(), который возвращает"Admin: {Username}, Email: {email}"— обратите внимание, что здесь вы можете получить доступ к защищенному полюemail!Program.cs: В основном файле создайте объектыUserProfileиAdminProfile, используя входные значения. Продемонстрируйте уровни доступа, вызывая доступные публичные методы и обращаясь к внутреннему полю напрямую (так как вы находитесь в той же сборке). Покажите, какую информацию может раскрыть каждый тип пользователя.
Вы получите пять входных данных:
- Username
- Password
- User ID (целое число)
- Попытка ввода пароля для проверки
Выведите результат в следующем формате:
Regular User:
{GetPublicInfo() result}
Internal ID: {userId}
Password valid: {ValidatePassword result}
Admin User:
{GetAdminInfo() result}Например, если входные данные: alice, secret123, alice@email.com, 1001 и secret123, вывод должен быть:
Regular User:
User: alice
Internal ID: 1001
Password valid: True
Admin User:
Admin: alice, Email: alice@email.comОбратите внимание, что пароль остается полностью скрытым — вы можете только проверить его, но никогда не получить. Электронная почта защищена (protected), поэтому только AdminProfile (производный класс) может ее раскрыть. Внутренний userId доступен из вашего основного файла, потому что он находится в той же сборке. Это инкапсуляция в действии!
Шпаргалка
Модификаторы доступа управляют видимостью и доступностью членов класса, формируя основу инкапсуляции в ООП.
C# предоставляет четыре основных модификатора доступа:
public class BankAccount
{
public string AccountHolder; // Доступно отовсюду
private decimal balance; // Только внутри этого класса
protected string accountType; // Этот класс и производные классы
internal int branchCode; // В пределах той же сборки
}public: доступен из любого кода
private: доступен только внутри того же класса (самый строгий, используется по умолчанию для членов класса)
protected: доступен из самого класса и любых производных классов
internal: доступен только в пределах той же сборки (проекта)
Если модификатор не указан, члены класса по умолчанию становятся private:
class Example
{
int secret; // private по умолчанию
}Лучшая практика: начинайте с private и увеличивайте видимость только при необходимости, чтобы предотвратить зависимость внешнего кода от деталей реализации.
Попробуйте сами
using System;
using Security;
class Program
{
public static void Main(string[] args)
{
// Чтение входных данных
string username = Console.ReadLine();
string password = Console.ReadLine();
string email = Console.ReadLine();
int userId = Convert.ToInt32(Console.ReadLine());
string passwordAttempt = Console.ReadLine();
// TODO: Создайте объект UserProfile с входными значениями
// TODO: Создайте объект AdminProfile с теми же входными значениями
// TODO: Выведите "Regular User:"
// TODO: Выведите результат GetPublicInfo()
// TODO: Выведите "Internal ID: ", а затем поле userId (доступно, так как находится в той же сборке)
// TODO: Выведите "Password valid: ", а затем результат ValidatePassword()
// TODO: Выведите "Admin User:"
// TODO: Выведите результат GetAdminInfo()
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыПространства имен и директивыВведение в классы и объектыКлючевое слово 'this'Методы и параметрыПоля и свойстваКонструкторыИнициализаторы объектовИтоги — Простой калькулятор4Наследование
Основы синтаксиса наследования (:)Ключевое слово 'base'Ключевые слова Virtual и OverrideЗапечатанные классыБазовый класс 'object'Итоги — Иерархия сотрудников7Продвинутые возможности
Перегрузка операторовИндексаторы (this[])Переопределение ToString()Методы расширенияПовторение — Пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПотокобезопасный SingletonПаттерн FactoryПаттерн Observer (События)Паттерн Strategy13Финальные испытания
Платформа для онлайн-обученияКомпонент игрового персонажаСервис аренды транспорта2Свойства и статические члены
Автоматически реализуемые свойстваСвойства только для чтения и записиСтатические поля и методыСтатические классыЧлены в виде выражений5Полиморфизм и интерфейсы
Полиморфизм: компиляция vs выполнениеИнтерфейс vs абстрактный классМножественные интерфейсыЯвные интерфейсыUpcasting и DowncastingИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция вместо наследованияGenerics (классы и методы)Делегаты и событияАтрибуты и рефлексияIDisposable и оператор usingОсновы Dependency Injection11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Архитектура классов
Экземплярные и статические данныеКлючевые слова 'readonly' и 'const'Опорные поляПовторение — Менеджер банковских счетов6Инкапсуляция
Модификаторы доступаСвойства для инкапсуляцииРеализация скрытия данныхПаттерны неизменяемостиИтоги — Записи студентов9Переменное количество аргументов
Ключевое слово 'params'Необязательные параметрыИменованные аргументыПерегрузка методов