C# - Объединение: Путеводитель для начинающих

Привет, будущий супергерой кодирования! Сегодня мы отправимся в увлекательное путешествие в мир C# и рассмотрим один из его основных концептов: Объединение (Encapsulation). Не волнуйтесь, если вы никогда не писали ни строчки кода раньше – я здесь, чтобы помочь вам на каждом шагу. Итак, погружаемся!

C# - Encapsulation

Что такое объединение?

Прежде чем мы перейдем к Details, давайте поймем, что такое объединение. Представьте, что у вас есть магическая коробка, которая может творить чудеса, но вам не нужно знать, как она работает внутри – вам нужно только знать, как ею пользоваться. Вот в чем суть объединения!

В C# объединение – это о том, чтобы связать данные (переменные) и методы, которые работают с этими данными, в единую единицу или объект. Это как создать защитную капсулу вокруг вашего кода, отсюда и название "объединение".

Теперь давайте рассмотрим, как C# реализует объединение с помощью спецификаторов доступа.

Спецификаторы доступа в C

Спецификаторы доступа – это ключевые слова, которые определяют доступность класса, метода или свойства в вашем коде. Представьте их как различные уровни допуска. C# предоставляет пять основных спецификаторов доступа:

  1. Public
  2. Private
  3. Protected
  4. Internal
  5. Protected Internal

Давайте разберем их один за другим.

Спецификатор доступа Public

Ключевое слово public – это как "пропуск на все мероприятия". Когда вы объявляете член как public, к нему можно получить доступ из любой части вашей программы.

public class Person
{
public string Name { get; set; }

public void SayHello()
{
Console.WriteLine($"Привет, мое имя {Name}!");
}
}

class Program
{
static void Main(string[] args)
{
Person person = new Person();
person.Name = "Алиса";  // Доступ к public свойству
person.SayHello();  // Вызов public метода
}
}

В этом примере и Name, и SayHello() являются public, поэтому мы можем доступа к ним напрямую из метода Main.

Спецификатор доступа Private

Теперь private – это как "зона только для персонала". Приватные члены могут быть доступны только внутри того же класса.

public class BankAccount
{
private double balance;

public void Deposit(double amount)
{
if (amount > 0)
{
balance += amount;
}
}

public double GetBalance()
{
return balance;
}
}

class Program
{
static void Main(string[] args)
{
BankAccount account = new BankAccount();
account.Deposit(100);
// account.balance = 1000000;  // Это вызовет ошибку!
Console.WriteLine($"Баланс: {account.GetBalance()}");
}
}

Здесь balance является private, поэтому мы не можем доступа к нему напрямую из класса BankAccount. Нам нужно использовать public методы, такие как Deposit() и GetBalance(), чтобы взаимодействовать с ним.

Спецификатор доступа Protected

Члены с protected доступны внутри того же класса и классами-наследниками. Это как "семейная зона".

public class Animal
{
protected string name;

public Animal(string name)
{
this.name = name;
}

protected void Eat()
{
Console.WriteLine($"{name} ест.");
}
}

public class Dog : Animal
{
public Dog(string name) : base(name) { }

public void Bark()
{
Console.WriteLine($"{name} лает!");  // Может доступа к protected члену
Eat();  // Может вызвать protected метод
}
}

class Program
{
static void Main(string[] args)
{
Dog dog = new Dog("Бuddy");
dog.Bark();
// dog.name = "Max";  // Это вызовет ошибку!
// dog.Eat();  // Это также вызовет ошибку!
}
}

В этом примере Dog может доступа к protected name и Eat() методу из родительского класса Animal, но мы не можем доступа к этим напрямую из Main.

Спецификатор доступа Internal

Члены с internal доступны внутри того же сборника (представьте себе скомпилированный .dll или .exe файл). Это как "зона только для сотрудников компании".

// В AssemblyOne.cs
internal class InternalClass
{
internal void InternalMethod()
{
Console.WriteLine("Это внутренний метод.");
}
}

// В Program.cs (тот же сборник)
class Program
{
static void Main(string[] args)
{
InternalClass obj = new InternalClass();
obj.InternalMethod();  // Это работает!
}
}

// В другом сборнике, это не сработает:
// InternalClass obj = new InternalClass();  // Ошибка!

Спецификатор доступа Protected Internal

Наконец, protected internal – это комбинация protected и internal. Он доступен внутри того же сборника или классами-наследниками в других сборниках.

// В AssemblyOne.cs
public class BaseClass
{
protected internal void ProtectedInternalMethod()
{
Console.WriteLine("Это метод protected internal.");
}
}

// В AssemblyTwo.cs
public class DerivedClass : BaseClass
{
public void CallProtectedInternalMethod()
{
ProtectedInternalMethod();  // Это работает!
}
}

// В Program.cs (AssemblyTwo)
class Program
{
static void Main(string[] args)
{
DerivedClass obj = new DerivedClass();
obj.CallProtectedInternalMethod();
// obj.ProtectedInternalMethod();  // Это не сработает!
}
}

Итог по спецификаторам доступа

Вот удобная таблица, резюмирующая уровни доступа:

Спецификатор доступа Тот же класс Класс-наследник (тот же сборник) Не наследующий класс (тот же сборник) Класс-наследник (другой сборник) Не наследующий класс (другой сборник)
Public Да Да Да Да Да
Private Да Нет Нет Нет Нет
Protected Да Да Нет Да Нет
Internal Да Да Да Нет Нет
Protected Internal Да Да Да Да Нет

И вот оно! Вы только что сделали свои первые шаги в мир объединения в C#. Запомните, что объединение – это о контроле доступа к вашему коду и данным. Это помогает вам писать более безопасные, maintainable и гибкие программы.

Пока вы продолжаете свое coding путешествие, вы обнаружите, что объединение становится второй натурой. Это как учиться ездить на велосипеде – сначала немного неуверенно, но вскоре вы будете мчаться без всяких усилий!

Продолжайте практиковаться, оставайтесь любопытными и счастливого кодирования!

Credits: Image by storyset