Введение в теорию программирования. Объектно-ориентированный подход

       

Рассмотрев интуитивное определение


Рассмотрев интуитивное определение понятия класса, а также представив домены как формальную модель классов языков программирования в целом, остановимся более подробно на классах в языке объектно-ориентированного программирования C#.

По аналогии с другими известными языками объектно-ориентированного программирования (в частности, C++ и Java), под классом в языке C# понимается ни что иное, как ссылочный тип, определенный пользователем.

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

Членами (или, иначе, элементами) класса языка программирования C# могут являться следующие конструкции:

  • константа, поле, метод, оператор, конструктор, деструктор;

  • свойство, индексатор, событие;

  • статические и инициализированные члены.

Доступ к членам класса определяется исходя из значения модификатора области действия идентификатора класса, который может принимать следующие значения: public, protected, private (данное значение используется по умолчанию), internal, protected internal.

Инициализация объекта класса языка программирования C# производится посредством оператора new, о котором будет рассказано ниже.

Рассмотрим манипулирование классами на примере следующих фрагментов программ на языке C#.

Прежде всего, приведем простейшее описание класса. Описание класса C c целочисленным полем value на языке C# имеет вид:

class C { ... int value = 0; ... }

Заметим, что в описании класса C на языке программирования C# кроме рассмотренного поля value могут присутствовать и другие поля (т.е. атрибуты объектов класса) допустимых в языке C# типов, а также методы (т.е. способы манипулирования объектами данного класса).

В языке программирования C# инициализация поля (т.е. связывание его с начальным значением) не является обязательной. Для обеспечения безопасности программного кода и в силу реализации принципа инкапсуляции, инициализация поля некоторого класса C не должна открывать возможностей для доступа к полям и методам данного типа.
При этом доступ к элементам класса внутри класса реализуется посредством обращения и не требует полного имени объекта:

... value ...

В отличие от предыдущего случая, доступ из сторонних классов требует указания полного имени объекта (в примере последовательно производятся инициализация и обращение):

C c = new C(); ... c.value ...

Рассмотрим более развернутый пример описания классов и манипулирования их элементами.

Приведем описание класса Rectangle, моделирующего прямоугольник с полями origin, width и height, моделирующими, соответственно, начальную точку (с парой координат), ширину и высоту, а также методом MoveTo, моделирующим перемещение начальной точки в заданную:

class Rectangle { Point origin; public int width, height; public Rectangle(){ origin = new Point(0,0); width=height=0; } public Rectangle ( Point p, int w, int h){ origin = p; width = w; height = h; } public void MoveTo (Point p) { origin = p; } }

Заметим, что модификатор области видимости для данного класса и его элементов разрешает общедоступное применение (public). Рассмотрим пример использования класса Rectangle:

Rectangle r = new Rectangle( new Point(10,20),5,5); int area = r.width * r.height; r.MoveTo(new Point(3,3));

Заметим, что в данном примере последовательно осуществляются инициализация объекта класса Rectangle с начальной точкой (10,20), шириной и высотой в пять единиц (т.е. квадрата), подсчет его площади area и перемещение начала отсчета в точку с координатами (3,3).

В результате анализа рассмотренных примеров становится очевидным, что объект является принципиально динамическим и изменяет состояние в зависимости от соотнесения (времени и внешних воздействий).

В этой связи исследуем более подробно простейший, статический случай полей объекта, который в языке программирования C# выделен в самостоятельный синтаксический элемент, характеризующийся независимостью от состояния объекта (и потому условно принадлежащий к классу). Приведем модифицированный пример предыдущего класса для случая статических полей:

class Rectangle { static Color defaultColor; // для каждого класса static readonly int scale; // для каждого класса int x, y, width,height; // для каждого объекта ... }

Заметим, что статические поля defaultColor и scale остаются неизменными внутри класса, тогда как динамические поля x, y, width и height индивидуально изменяются в зависимости от состояния каждого из объектов класса. Доступ изнутри класса осуществляется посредством обращения:

... defaultColor ... scale ...

а из внешних классов - посредством обращения:

... Rectangle.defaultColor ... Rectangle.scale ...

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


Содержание раздела