Язык C# в существенной степени является объектно-ориентированным языком программирования. Все типы языка принадлежат к одной из следующих категорий:
1. Перечислимые типы.
2. Структурные типы.
3. Классы.
4. Интерфейсы.
5. Делегаты.
Перечислимые и структурные типы играют в языке сравнительно скромную роль. С интерфейсами и делегатами Вы познакомитесь позже. Большинство типов гигантской библиотеки базовых классов .NET являются классами. Даже примитивные встроенные типы реализованы с помощью классов (int – с помощью Int32 и т.д.). И что самое удивительное – у всех этих тысяч классов имеется общий базовый класс, который называется Object. Любой Ваш собственный класс имеет неявный базовый класс Object, а вместе с ним и несколько унаследованных членов. На данный момент трудно во всех подробностях объяснить преимущества такого подхода. Однако простой аргумент очевиден уже сейчас – класс Object является отправной точкой всей системы классов. А поскольку в C# не поддерживается множественное наследование (класс не может быть наследником несколькихз базовых классов), вся система классов имеет аккуратную древовидную структуру.
В предыдущем примере производный класс, выполняя свой метод SayCourses, получает доступ к значению переменной name с помощью свойства Name. Это кажется немного странно, поскольку переменная name унаследована классом Student от класса Person и, таким образом, входит в состав каждого объекта класса Student. Однако, поскольку в классе Person переменная name описана как закрытая (private), она недоступна даже внутри своего производного класса Student.
Эта ситуация встречается часто при использовании производных классов, что ухудшает производительность программы за счет «лишних» вызовов методов и свойств. Для преодоления этой проблемы в языке C# имеется еще один уровень защиты переменных, обозначаемый ключевым словом protected. Такие «защищенные» переменные становятся непосредственно доступны не только в своем классе, но и во всех производных от него.
Если в классе Person переменную name описать как защищенную:
protected string name;
в реализации метода SayCourses можно напрямую обращаться к переменной:
String.Format("{0}.изучает следующие курсы:\n",Name);
Наследование нашло свое наглядное отражение и на диаграммах классов UML. Базовый и производный класс соединяются стрелкой с треугольным наконечником как показано на следующей диаграмме:
Обратите внимание, что здесь используется нестандартный вариант диаграммы классов, используемый только в рамках средств разработки Microsoft. На таких диаграммах тело класса, кроме переменных (Fields) и методов (Methods), может содержать отдельный перечень свойств (Properties). Кроме того, перед каждым членом класса указывается некоторый значок, который заменяет собой модификатор доступа и указывает на категорию элемента класса.
Стандартный UML имеет большее распространение и позволяет разработчикам эффективно общаться, независимо от используемых средств разработки.