Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теория_к_экзамену_ООП.doc
Скачиваний:
7
Добавлен:
01.03.2025
Размер:
422 Кб
Скачать
☆

Модификатор static и объект this Кроме выше рассмотренных модификаторов доступа (public,protected…) в языке c# существует еще ряд модификаторов. Один из них – модификатор static.

Модификатор static указывает, что член класса принадлежит самому классу, а не его экземпляру. Даже если в отдельном приложении создается множество экземпляров класса, в нем существует только одна копия члена с модификатором static. При доступе к члену с модификатором static следует ссылаться на класс, на не на его экземпляр. Однако в рамках объявления члена класса к членам static можно обращаться с помощью объекта this.

Модификатором static можно помечать члены классов. Классы, интерфейсы и члены интерфейсов не могут иметь модификатора static.

class CTest {

var nonstaticX : int; // A non-static field belonging to a class instance.

static var staticX : int; // A static field belonging to the class.

}

// Initialize staticX. An instance of test is not needed.

CTest.staticX = 42;

// Create an instance of test class.

var a : CTest = new CTest;

a.nonstaticX = 5;

// The static field is not directly accessible from the class instance.

print(a.nonstaticX);

print(CTest.staticX);

Нестатический метод класса определяет индивидуальное поведение объекта и поэтому вызывается "от имени" данного объекта. В большинстве объектно-ориентированных языков программирования реализована возможность непосредственного обращения из нестатического метода (а также свойства) к объекту, который обеспечил выполнение кода данного метода или свойства. Аналогичная возможность обращения к объекту реализуется в теле нестатических конструкторов и деструктора.

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

По своей сути первичное выражение this в данном контексте является ссылкой на объект, обеспечивающий выполнение данного кода.

Если метод возвращает ссылку на объект, который вызвал данный метод, this можно использовать в качестве возвращаемого значения оператора return.

Для метода ToString все ссылки на объекты, представляющие данный класс, неразличимы. Следующий пример подтверждает тот факт, что this в нестатическом методе является всего лишь ссылкой на объект — представитель данного класса.

using System;

namespace XXX

{

class TEST

{

int x;

int y;

public string str;

public TEST(int xKey, int yKey)

{

// В конструкторе this – это всегда ссылка

// на создаваемый объект

this.x = xKey;

y = yKey;

str = "Ha-Ha-Ha";

}

public TEST f1(string strKey)

{

this.str = this.str + strKey + this.ToString();

// Здесь можно будет посмотреть,

// что собой представляет значение ссылки на объект.

return this; // А вот здесь без выражения this просто

// ничего не получается.

}

}

class Program

{

static void Main(string[] args)

{

TEST t, tM;

t = new TEST(10, 10);

Console.WriteLine(t.str);

tM = t.f1(" from ");

t = new TEST(100, 100);

Console.WriteLine(t.str);

Console.WriteLine(t.ToString());

Console.WriteLine(tM.str);

Console.WriteLine(tM.ToString());

}

}

}

this в заголовке конструктора

Конструктор не вызывается. Передача управления конструктору осуществляется при выполнении операции new.

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

Для сокращения размера кода можно оставить ОДИН конструктор, выполняющий ВСЮ "черновую" обязательную работу по созданию объектов. Тонкую настройку объектов можно производить после выполнения кода конструктора, непосредственно вызывая соответствующие методы-члены. При этом методы вызываются именно ПОСЛЕ того, как отработает конструктор.

Можно также определить множество специализированных конструкторов, после выполнения которых следует вызывать дополнительный метод инициализации для общей "достройки" объекта.

И то и другое — некрасиво. Код получается сложный.

В C# реализован другой подход, который состоит в следующем:

  • определяется множество разнообразных специализированных конструкторов;

  • выделяется наименее специализированный конструктор, которому поручается выполнение обязательной работы;

  • обеспечивается передача управления из конструктора конструктору.

Вот так this в контексте конструктора обеспечивает в C# передачу управления от конструктора к конструктору. Таким образом, программист освобождается от необходимости повторного кодирования алгоритмов инициализации для каждого из вариантов конструктора.

Следующий фрагмент программного кода демонстрирует объявление нескольких конструкторов с передачей управления "золушке":

class Point2D

{

private float x, y;

public Point2D(float xKey, float yKey)

{

Console.WriteLine("Point2D({0}, {1}) is here!", xKey, yKey);

// Какой-нибудь сложный обязательный

// код инициализации данных – членов класса.

int i = 0;

while (i < 100)

{

x = xKey;

y = yKey;

i++;

}

}

// А все другие конструкторы в обязательном порядке предполагают

// регламентные работы по инициализации значений объекта – и делают при этом

// еще много чего...

public Point2D():this(0,0)

{

int i;

for (i = 0; i < 100; i++)

{

// Хорошо, что значения уже проинициализированы!

// Здесь своих проблем хватает.

}

Console.WriteLine("Point2D() is here!");

}

public Point2D(Point2D pKey):this(pKey.x, pKey.y)

{

int i;

for (i = 0; i < 100; i++)

{

// Здесь тоже заблаговременно позаботились о значениях.

// Хорошо.

}

Console.WriteLine("Point2D({0}) is here!", pKey.ToString());

}

}