Структура ИЛИ класс. Пример 1

В статье «Классы или структуры, в чем отличия» приведены небольшие примеры, которые, как показал опыт общения с начинающими программистами, недостаточны для более глубокого понимания этих различий. Поэтому будет полезно рассмотреть еще примеры.
Ключевое слово здесь, как предлагает в комментариях Руслан, альтернатива (структура или класс), т.е. когда что выбирать. Рекомендую обязательно эксперименты проводить в среде VS (не теоретически — лучше поймете!).

Эксперимент №1.

Для быстрого анализа в тексте  примера 1 (файл Class2.cs) заменим только строку public class MFC на public struct MFC и запустим проект.
Получим 6 сообщений об ошибках:

Ошибка CS0106 Модификатор "virtual" недопустим для этого элемента.
Ошибка CS0106 Модификатор "virtual" недопустим для этого элемента.
Ошибка CS0106 Модификатор "virtual" недопустим для этого элемента.
Ошибка CS0666 '"MFC.mother": новый защищенный член объявлен в структуре.
Ошибка CS0666 '"MFC.father": новый защищенный член объявлен в структуре.
Ошибка CS0666 '"MFC.child": новый защищенный член объявлен в структуре.

Анализ:
1) Первые три ошибки связаны с объявлением методов GetChild(), Output(), Tir() как virtual.
Вывод: модификатор virtual к методам структур не применим. Тем не менее, модификатор public имеет в структуре то же назначение, что и в классе — обеспечить доступ к данным.
2) Другие три ошибки связаны с объявлением в нашей структуре MFC полей mother; father; child с модификатором protected (в классе мы их так объявили, так как предполагали их защиту и наследование, см. Пример 2).
Вывод:
Удалим модификатор protected, тем самым тип этих полей станет private (по умолчанию). Конечно, можно было бы явно вместо protected указать public, однако это будет неверно с позиций защиты данных.
Удалим лишнее, тогда получим в файле Class2.cs:

// структура вместо класса
using System;
namespace МатьОтецРебенок
{
// Инкапсуляция в структуре MFC
   public struct MFC
   {
      string mother;
      string father;
      string child;
      public MFC(string m, string f, string c)
      {
         mother = m;
         father = f;
         child = c;
      }
      // возврат имени ребенка
      public string GetChild()
      {
         return child;
      }
      // вывод имен членов семьи
      public void Output()
      {
         Console.WriteLine("Mать: " + mother + " отец: " + father);
         Console.WriteLine("Ребенок: " + child);
      }
      // Рисование разграничительной линии (пригодится)
      public void Tir()
      {
         Console.WriteLine("_____________________________");
      }
   }
}

Текст файла Program.cs оставим без изменений:

using System;
namespace МатьОтецРебенок
{
    class Program
    {
        static void Main()
        {
            // R - экземпляр 
            MFC R = new MFC("Барбара", "Борис", "Бэлла");
            R.Output();
            R.Tir();    // разделитель информации 

            // Дети и фамилия
            Console.WriteLine("Дети: " + R.GetChild());
            R.Tir();
        }
    }
}

Результат:

Mать: Барбара отец: Борис
Ребенок: Бэлла
_____________________________
Дети: Бэлла
_____________________________

В точном соответствии с Примером 1 на базе класса MFC. При необходимости разберите его отдельно.

Эксперимент 2.

Что произойдет, если мы удалим (удобнее просто пока закомментировать) конструктор public MFC(string m, string f, string c) { }.
Результат компиляции:

Ошибка CS1729 'MFC" не содержит конструктор, который принимает аргументы 3.

Конечно понятна причина, в Main() имеется оператор MFC R = new MFC(«Барбара», «Борис», «Бэлла»);, предполагающий создание экземпляра структуры с конкретными значениями полей.
Если так нельзя, то попробуем задать для структуры конструктор без параметров, например такой:

public MFC() 
{
   mother = "M";
   father = "F";
   child = "C";
}

Примечание. Конечно, особого смысла такой конструктор с постоянными полями не имеет, но нам важно понять отличия структуры от класса.

Соответственно в Main() оператор MFC R = new MFC(«Барбара», «Борис», «Бэлла»); заменим на MFC R = new MFC();.
Результат компиляции:

Ошибка	CS0568	Структуры не могут содержать явных конструкторов без параметров.

Вывод 1: Для структур нельзя создать конструктор по умолчанию (без параметров).

А если выполнить обратную замену? Вместо struct напишем снова class? Тогда все замечательно, ошибок нет, результат проверки:

Mать: M отец: F
Ребенок: C
_____________________________
Дети: C
_____________________________

Вывод 2: Для класса создание конструктора без параметров вполне допустимо.

Эксперимент №3.

Если в последнем случае (с классом) вообще удалим конструктор класса MFC. Тогда при выполнении оператора MFC R = new MFC(); объект будет все таки создан, но с пустыми полями (так как они типа string, то их значения = null). И вот результат:

Mать:  отец:
Ребенок:
_____________________________
Дети:
_____________________________ 

Вывод. Если конструктор в описании класса отсутствует, то он по умолчанию все таки создается, равно как и полям объекта присваиваются начальные значения.

Итоги экспериментов:

  1. Замена структуры на класс происходит без особых проблем, однако при замене класса структурой могут возникать ошибки.
  2. Использование структур исключает наследование. Совет: Если Вы четко определились с конструкцией данных — используйте структуры, иначе — классы.
  3. Структура не может содержать явного конструктора без параметров, однако он уже существует по умолчанию.
  4. Создание конструктора класса без параметров вполне допустимо.
  5. При отсутствии конструктора в описании класса он создается по умолчанию.

Сравните эти выводы с таблицей, где сравниваются классы и структуры, см. «Классы или структуры, в чем отличия» .

Продолжение следует.

2 комментария к “Структура ИЛИ класс. Пример 1”

  1. В этом небольшом уроке мы поговорим об альтернативе классам — структурах. Структура – это более простая версия классов. Все структуры наследуются от базового класса

    1. Вячеслав Рычков

      Руслан! Я понимаю, что Вы торопите меня раскрыть тему. Спасибо. Насчет наследования структур от базового класса — подумаю.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Пролистать наверх