.RU

Введение в C#: классы

Вадим Бодров

Система классов играет важную роль в современных языках программирования. Как же они реализованы в новом языке C#, созданном корпорацией Microsoft, и зачем нужно изучать С#?

Ответы на эти вопросы зависят от того, как вы собираетесь работать дальше. Если вы хотите создавать приложения для платформы .NET, то вам, скорее всего, не удастся избежать изучения C#. Конечно, можно использовать и Си++, и Visual Basic или любой язык программирования, тем более что независимыми разработчиками создаются трансляторы с APL, Кобола, Eiffel, Haskell, Оберона, Smalltalk, Perl, Python, Паскаля и др. Однако для компилятора, способного генерировать приложения среды .NET CLR (Common Language Runtime), только C# является «родным» языком. Он полностью соответствует идеологии .NET и позволяет наиболее продуктивно работать в среде CLR. В свое время для использования виртуальной машины Java было создано множество так называемых «переходников» (bridges) c различных языков программирования, в частности PERCobol, JPython, Eiffel-to-JavaVM System, Tcl/Java и т.д. Подобные разработки так и не получили должного распространения. Практика показала, что значительно проще изучить новый язык, чем вводить дополнительные расширения в менее подходящую для данных целей систему программирования. И не надо быть провидцем, чтобы утверждать, что бо,льшая часть программистов, создающих приложения для платформы .NET, отдаст предпочтение именно языку C#.

C# является языком объектно-ориентированного программирования, поэтому классы играют в нем основополагающую роль. Более того, все типы данных C#, как встроенные, так и определенные пользователем, порождены от базового класса object. Иными словами, в отличие от Java, где примитивные типы данных отделены от объектных типов, все типы данных в C# являются классами и могут быть разделены на две группы:

ссылочные (reference types);

обычные (value types).

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

using System;

class CValue

{

public int val;

public CValue(int x) {val = x;}

}

class Example_1

{

public static void Main()

{

CValue p1 = new CValue(1);

CValue p2 = p1;

Console.WriteLine(”p1 = {0}, p2 = {1}”,

p1.val, p2.val);

p2.val = 2;

Console.WriteLine(”p1 = {0}, p2 = {1}”,

p1.val, p2.val);

}

}

Откомпилировав и выполнив программу, получим следующий результат:

p1 = 1, p2 = 1

p1 = 2, p2 = 2

Как нетрудно видеть, p2 является всего лишь ссылкой на p1. Тем самым становится очевидно, что при изменении поля val экземпляра класса p2 в действительности изменяется значение соответствующего поля p1. Подобный подход не очень удобен при работе с примитивными типами данных, которые должны содержать само значение, а не ссылку на него (Complex, Point, Rect, FileInfo и т.д.). Для описания таких объектов и предназначены типы значений:

using System;

struct SValue

{

public int val;

public SValue(int x) {val = x;}

}

class Example_2

{

public static void Main()

{

SValue p1 = new SValue(1);

SValue p2 = p1;

Console.WriteLine(”p1 = {0}, p2 = {1}”,

p1.val, p2.val);

p2.val = 2;

Console.WriteLine(”p1 = {0}, p2 = {1}”,

p1.val, p2.val);

}

}

Вот что получится после запуска вышеприведенной программы:

p1 = 1, p2 = 1

p1 = 1, p2 = 2

Из этого следует, что экземпляр класса p2 является самостоятельным объектом, который содержит собственное поле val, не связанное с p1. Использование обычных типов позволяет избежать дополнительного расходования памяти, поскольку не создаются дополнительные ссылки, как в случае с экземплярами классов. Конечно, экономия невелика, если у вас имеется всего несколько небольших объектов типа Complex или Point. Зато для массива, содержащего несколько тысяч таких элементов, картина может в корне измениться. В таблице приведены основные отличия типов class и struct.

Интерфейсы

Классы в языке C# претерпели довольно серьезные изменения по сравнению с языком программирования Cи++, который и был взят за основу. Первое, что бросается в глаза, это невозможность множественного наследования. Такой подход уже знаком тем, кто пишет на языках Object Pascal и Java, а вот программисты Cи++ могут быть несколько озадачены. Хотя при более близком рассмотрении данное ограничение уже не кажется сколь-нибудь серьезным или непродуманным. Во-первых, множественное наследование, реализованное в Cи++, нередко являлось причиной нетривиальных ошибок. (При том что не так уж часто приходится описывать классы с помощью множественного наследования.) Во-вторых, в C#, как и в диалекте Object Pascal фирмы Borland, разрешено наследование от нескольких интерфейсов.

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

using System;

class CShape

{

bool IsShape() {return true;}

}

interface IShape

{

double Square();

}

class CRectangle: CShape, IShape

{

double width;

double height;

public CRectangle(double width, double height)

{

this.width = width;

this.height = height;

}

public double Square()

{

return (width * height);

}

}

class CCircle: CShape, IShape

{

double radius;

public CCircle(double radius)

{

this.radius = radius;

}

public double Square()

{

return (Math.PI * radius * radius);

}

}

class Example_3

{

public static void Main()

{

CRectangle rect = new CRectangle(3, 4);

CCircle circ = new CCircle(5);

Console.WriteLine(rect.Square());

Console.WriteLine(circ.Square());

}

}

Оба объекта, rect и circ, являются производными от базового класса CShape и тем самым они наследуют единственный метод IsShape(). Задав имя интерфейса IShape в объявлениях CRectangle и CCircle, мы указываем на то, что в данных классах содержится реализация всех методов интерфейса IShape. Кроме того, члены интерфейсов не имеют модификаторов доступа. Их область видимости определяется непосредственно реализующим классом.

Свойства

Рассматривая классы языка C#, просто нельзя обойти такое «новшество», как свойства (properties). Надо сказать, что здесь чувствуется влияние языков Object Pascal и Java, в которых свойства всегда являлись неотъемлемой частью классов. Что же представляют собой эти самые свойства? С точки зрения пользователя, свойства выглядят практически так же, как и обычные поля класса. Им можно присваивать некоторые значения и получать их обратно. В то же время свойства имеют бо,льшую функциональность, так как чтение и изменение их значений выполняется с помощью специальных методов класса. Такой подход позволяет изолировать пользовательскую модель класса от ее реализации. Поясним данное определение на конкретном примере:

using System;

using System.Runtime.InteropServices;

class Screen

{

[DllImport(”kernel32.dll”)]

static extern bool SetConsoleTextAttribute(

int hConsoleOutput, ushort wAttributes

);

[DllImport(”kernel32.dll”)]

static extern int GetStdHandle(

uint nStdHandle

);

const uint STD_OUTPUT_HANDLE = 0x0FFFFFFF5;

static Screen()

{

output_handle = GetStdHandle(STD_OUTPUT_HANDLE);

m_attributes = 7;

}

public static void PrintString(string str)

{

Console.Write(str);

}

public static ushort Attributes

{

get

{

return m_attributes;

}

set

{

m_attributes = value;

SetConsoleTextAttribute(output_handle, value);

}

}

private static ushort m_attributes;

private static int output_handle;

}

class Example_4

{

public static void Main()

{

for (ushort i = 1; i < 8; i++)

{

Screen.Attributes = i;

Screen.PrintString(”Property Demo

”);

}

}

}

Программа выводит сообщение «Property Demo», используя различные цвета символов (от темно-синего до белого). Давайте попробуем разобраться в том, как она работает. Итак, сначала мы импортируем важные для нас функции API-интерфейса Windows: SetConsoleTextAttribute и GetStdHandle. К сожалению, стандартный класс среды .NET под названием Console не имеет средств управления цветом вывода текстовой информации. Надо полагать, что корпорация Microsoft в будущем все-таки решит эту проблему. Пока же для этих целей придется воспользоваться службой вызова платформы PInvoke (обратите внимание на использование атрибута DllImport). Далее, в конструкторе класса Screen мы получаем стандартный дескриптор потока вывода консольного приложения и помещаем его значение в закрытую переменную output_handle для дальнейшего использования функцией SetConsoleTextAttribute. Кроме этого, мы присваиваем другой переменной m_attributes начальное значение атрибутов экрана (7 соответствует белому цвету символов на черном фоне). Заметим, что в реальных условиях стоило бы получить текущие атрибуты экрана с помощью функции GetConsoleScreenBufferInfo из набора API-интерфейса Windows. В нашем же случае это несколько усложнило бы пример и отвлекло от основной темы.

В классе Screen мы объявили свойство Attributes, для которого определили функцию чтения (getter) и функцию записи (setter). Функция чтения не выполняет каких-либо специфических действий и просто возвращает значение поля m_attributes (в реальной программе она должна бы возвращать значение атрибутов, полученное с помощью все той же GetConsoleScreenBufferInfo). Функция записи несколько сложнее, так как кроме тривиального обновления значения m_attributes она вызывает функцию SetConsoleTextAttribute, устанавливая заданные атрибуты функций вывода текста. Значение устанавливаемых атрибутов передается специальной переменной value. Обратите внимание на то, что поле m_attributes является закрытым, а стало быть, оно не может быть доступно вне класса Screen. Единственным способом чтения и/или изменения этого метода является свойство Attributes.

Свойства позволяют не только возвращать и изменять значение внутренней переменной класса, но и выполнять дополнительные функции. Так, они позволяют произвести проверку значения или выполнить иные действия, как показано в вышеприведенном примере.

В языке C# свойства реализованы на уровне синтаксиса. Более того, рекомендуется вообще не использовать открытых полей классов. На первый взгляд, при таком подходе теряется эффективность из-за того, что операции присваивания будут заменены вызовами функций getter и setter. Отнюдь! Среда .NET сгенерирует для них соответствующий inline-код.


zakon-pro-zovnshnoekonomchnu-dyanst-ukrani.html
zakon-respubliki-buryatiya-stranica-4.html
zakon-rf-o-gosudarstvennoj-tajne.html
zakon-rsfsr-ot-15-12-1978-ob-ohrane-i-ispolzovanii-pamyatnikov-istorii-i-kulturi.html
zakon-sohraneniya-momenta-impulsa.html
zakon-ukraini-o-zanyatosti-naseleniya.html
  • shpargalka.bystrickaya.ru/uchebniki-izdatelstva-drofa-voshedshie-v-federalnij-perechen-uchebnikov-rekomendovannih-dopushennih-stranica-7.html
  • zanyatie.bystrickaya.ru/tema-5-nv-gogol-kafedra-russkoj-i-zarubezhnoj-literaturi-uchebno-metodicheskij-kompleks-po-discipline-istoriya.html
  • assessments.bystrickaya.ru/dnevnik-3ritual-prizivanie-solnca-kniga-pervaya.html
  • thescience.bystrickaya.ru/izdanie-osushestvleno-v-ramkah-programmi-pushkin-pri-podderzhke-ministerstva-inostrannih-del-francii-i-posolstva-francii-v-rossii-stranica-16.html
  • control.bystrickaya.ru/dogovor-faktoringa-chast-2.html
  • exchangerate.bystrickaya.ru/genrih-ii-korol-francii.html
  • learn.bystrickaya.ru/glava-xxvi-biogennaya-migraciya-gumilevskij-l-i-vernadskij-3-e-izd.html
  • universitet.bystrickaya.ru/tematicheskij-plan-zanyatij-diethelm-kleiner-p-rofessora-mikrobiologii-universiteta-bajresa-dlya-studentov-2-kursa-v-ramkah-disciplini-mikrobiologiya-tema-lekcii.html
  • grade.bystrickaya.ru/monin-m-a-ovidij-v-tomah-voprosi-filosofii-2002-6-s-163-177.html
  • doklad.bystrickaya.ru/volteryanci-i-volteryanki.html
  • studies.bystrickaya.ru/kostromskaya-oblast-v-2011g-napravila-pochti-700-mln-rub-na-remont-dorog-zasedanie-molodezhnoj-palati-9-socialnaya-podderzhka-10.html
  • education.bystrickaya.ru/--1-informatika-kak-nauchnaya-disciplina-ponyatie-informacii.html
  • tetrad.bystrickaya.ru/urok-masterskaya-tema-chichikov-i-chichikovshina.html
  • otsenki.bystrickaya.ru/sho-blm-basarmasini-shiis-rlk-ortalii-regionalnij-centr-shiis-upravleniya-obrazovaniya-vko.html
  • prepodavatel.bystrickaya.ru/t-talantov-aleksandr-petrovich-redakcionnaya-kollegiya-zavyalov-e-a.html
  • shkola.bystrickaya.ru/raschyot-i-proektirovanie-malomoshnih-bipolyarnih-tranzistorov.html
  • esse.bystrickaya.ru/razdel-3-prezidentskaya-programma-molodezh-rossii-napravleniya-realizacii-predislovie.html
  • znanie.bystrickaya.ru/analiz-mikrosredi-rekomendacii-35-makro-uroven-36-otraslevoj-uroven-39-mikro-uroven-44-monitoring-i-ocenka-47.html
  • teacher.bystrickaya.ru/glava-tridcat-vosmaya-kniga-pervaya.html
  • institute.bystrickaya.ru/glava-109-ocr-rock-mover-posvyashaetsya-s-a.html
  • abstract.bystrickaya.ru/-98-iz-proekta-revizovavshego-zakavkazskij-kraj-senatora-ei-mechnikova-o-preobrazovanii-sistemi-upravleniya-v-zakavkaze-i-kolonizacii-kraya-mezhdu-1830-g-20-yanvarya-1831-g.html
  • lektsiya.bystrickaya.ru/prilozhenie-5-k-dokumentacii-ob-aukcionestroitelstvo-federalnoj-avtodorogi-m-27-dzhubga-sochi-do-granici-s-gruziej-na-uchastke-adler-veseloe-stranica-12.html
  • doklad.bystrickaya.ru/uchitel-nachalnih-klassov-trofimenko-n-a.html
  • ucheba.bystrickaya.ru/programma-po-discipline-transportnaya-logistika-dlya-studentov-5-kursa-fakulteta-vneshnetorgovogo-menedzhmenta.html
  • universitet.bystrickaya.ru/statya-47-municipalnie-zaimstvovaniya-statya-pravovoj-status-mo-konevskoe.html
  • klass.bystrickaya.ru/babushka-otsidit-za-rodnogo-vnuka-zakonoproekt-soderzhit-normi-kotorie-v-sovremennih-usloviyah-mogut-stat-ugrozoj-dlya-semi.html
  • esse.bystrickaya.ru/psihodelicheskaya-utopiya-istochniki-citat-stranica-12.html
  • occupation.bystrickaya.ru/obshestvenno-politicheskaya-gazeta-krimskoe-vremya.html
  • control.bystrickaya.ru/dvoryanskoe-gnezdo-stranica-2.html
  • uchenik.bystrickaya.ru/glava-vosmaya-nikolas-sparks-nezabivaemaya-progulka.html
  • composition.bystrickaya.ru/osnovi-veterinarii.html
  • occupation.bystrickaya.ru/obshaya-trudoemkost-disciplini-sostavlyaet-3-zachetnie-edinici-108-ch.html
  • institut.bystrickaya.ru/temi-referatov-dlya-otcheta-zaochnikov-2005-2006gg-ponyatie-o-gosudarstve-priznaki-gosudarstva-stranica-8.html
  • ekzamen.bystrickaya.ru/ris-1013-osvobozhdenie-ot-zahvata-za-kisti-ruk-ponyatiya-i-opredeleniya-ispolzuemie-v-medicinskoj-podgotovke.html
  • znaniya.bystrickaya.ru/put-k-zhiznestroyu-razumnogo-chelovechestva-dobroj-voli-teoreticheskaya-platforma-i-rukovodstvo-k-dejstviyu-vseh-dobronravnih-lyudej-stranica-30.html
  • © bystrickaya.ru
    Мобильный рефератник - для мобильных людей.