Menu
Coddy logo textTech

Модификаторы доступа

Часть раздела Объектно-ориентированное программирование путешествия по 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 и увеличивайте видимость только тогда, когда для этого есть веская причина. Это предотвращает зависимость другого кода от деталей реализации, которые вы, возможно, захотите изменить позже.

challenge icon

Задание

Легко

Давайте создадим безопасную систему профилей пользователей, которая демонстрирует, как модификаторы доступа защищают конфиденциальные данные, открывая только то, что необходимо. Вы создадите класс, в котором различные фрагменты информации имеют разные уровни видимости в зависимости от того, кто должен иметь к ним доступ.

Вы организуете свой код в трех файлах:

  • UserProfile.cs: Создайте класс UserProfile в пространстве имен Security, который управляет информацией о пользователе с соответствующими уровнями доступа. Профиль должен иметь:
    • public свойство Username (string) — имя пользователя может видеть кто угодно
    • private поле password (string) — доступ к нему должен иметь только сам класс
    • protected поле email (string) — доступ к нему может иметь класс и его производные классы
    • internal поле userId (int) — доступно внутри той же сборки
    Включите конструктор, который принимает username, password, email и userId. Добавьте 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
  • Email
  • 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()
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование