- •Роль инкапсуляции
 - •Роль наследования
 - •Роль полиморфизма
 - •Конструкторы
 - •Конструктор копирования
 - •Деструкторы
 - •Перегрузка методов
 - •Перегрузка операторов
 - •Перегрузка бинарных операторов
 - •Перегрузка унарных операторов
 - •Выполнение операций со встроенными в с# типами данных
 - •Переопределение методов Перекрытие методов
 - •Сокрытие методов
 - •Вызов базовых версий методов
 - •Область видимости переменных
 - •Конфликты областей видимости локальных переменных
 - •Конфликты областей видимости полей и локальных переменных
 - •Константы
 - •Модификаторы доступа
 - •Пространства имен
 - •Uml. Диаграмма вариантов использования. Привести пример.
 - •Чтение схем вариантов использования
 - •Субъекты, варианты использования и подсистемы
 - •Структурирование вариантов использования
 - •Количество элементов между субъектами и вариантами использования
 - •Задание количества элементов в ассоциации
 - •Uml. Диаграмма классов. Привести пример.
 - •Типы атрибутов и операций
 - •Несколько типов
 - •Атрибуты и ассоциации
 - •Обобщение
 - •Реализация
 - •Uml. Диаграмма последовательности. Привести пример.
 - •Создание схемы последовательностей
 - •Изменение порядка сообщений
 - •Перемещение или копирование последовательностей сообщений на схеме последовательностей
 - •Оптимизация размещения элементов на схеме последовательностей
 - •Изменить пакет, владеющий взаимодействием
 - •Типы сообщений
 - •Создание заметок о взаимодействиях
 - •Инициирующее событие
 - •Уровень детализации
 - •Uml. Диаграмма деятельности. Привести пример. Простые потоки управления
 - •Параллельные потоки
 - •Потоки данных
 - •Основные этапы создания схем активности
 - •Uml. Диаграмма кооперации. Привести пример.
 - •Uml. Диаграмма состояний. Привести пример.
 - •Понятие состояния объекта
 - •Переход
 - •Сложные переходы
 - •Переходы между параллельными состояниями
 - •Переходы между составными состояниями
 - •Синхронизирующие состояния
 - •Uml. Диаграмма компонентов. Диаграмма развертывания. Привести пример.
 - •Структурный паттерн проектирования «Компоновщик». Привести пример.
 - •Структурный паттерн проектирования «Оболочка». Привести пример.
 - •Структурный паттерн проектирования «Мост». Привести пример.
 - •Структурный паттерн проектирования «Адаптер». Привести пример.
 - •Структурный паттерн проектирования «Заместитель». Привести пример.
 - •Структурный паттерн проектирования «Приспособленец». Привести пример.
 - •Поведенческий паттерн проектирования «Команда». Привести пример.
 - •Поведенческий паттерн проектирования «Наблюдатель». Привести пример.
 - •Поведенческий паттерн проектирования «Состояние». Привести пример.
 - •Поведенческий паттерн проектирования «Итератор». Привести пример.
 - •Поведенческий паттерн проектирования «Цепочка обязанностей». Привести пример.
 - •Поведенческий паттерн проектирования «Шаблонный метод». Привести пример.
 - •Порождающий паттерн проектирования «Абстрактная фабрика». Привести пример.
 - •Порождающий паттерн проектирования «Абстрактный метод». Привести пример.
 - •Порождающий паттерн проектирования «Одиночка». Привести пример.
 - •Порождающий паттерн проектирования «Прототип». Привести пример.
 - •Порождающий паттерн проектирования «Строитель». Привести пример
 - •Архитектурный шаблон проектирование mvc. Привести пример. Введение
 - •«Оригинальный» mvc
 - •Model (Модель)
 - •View (Представление)
 - •Controller (Контроллер)
 - •Недостатки mvc и Document-View
 - •Почему интерфейс?
 - •Отличия от mvc
 - •Заключение
 
Конфликты областей видимости полей и локальных переменных
В некоторых случаях два идентификатора с одинаковыми именами (хотя и не совпадающими полностью уточненными именами) и одинаковой областью видимости можно различить, и тогда компилятор допускает объявление второй переменной. Причина в том, что С# делает принципиальное различие между переменными, объявленными на уровне типа (полями) и переменными, объявленными в методах (локальными). Рассмотрим следующий фрагмент кода:
using System;
namespace ConsoleApplication1
{
class Program
{
static int j = 20;
public static void Main()
{
int j = 30;
Console.WriteLine(j);
return;
}
}
Этот код компилируется, несмотря на то, что здесь в контексте метода Main() присутствуют две переменных с именем j: переменная j, определенная на уровне класса и существующая до тех пор, пока не будет уничтожен класс (когда завершится метод Main(), а вместе с ним и программа), и переменная j, определенная внутри Main(). В данном случае новая переменная с именем j, объявленная в методе Main(), скрывает переменную уровня класса с тем же именем. Поэтому когда вы запустите этот код, на дисплее будет отображено число 30.
Константы
Как следует из названия, константа — это переменная, значение которой не меняется за время ее существования. Предваряя переменную ключевым словом const при ее объявлении и инициализации, вы объявляете ее как константу:
const int a = 100; // Это значение не может быть изменено
Ниже перечислены основные характеристики констант:
Они должны инициализироваться при объявлении, и однажды присвоенные им значения никогда не могут быть изменены.
Значение константы должно быть вычислено во время компиляции. Таким образом, инициализировать константу значением, взятым из другой переменной, нельзя. Если все-таки нужно это сделать, используйте поля только для чтения.
Константы всегда неявно статические. Однако вы не должны (и фактически не можете) включать модификатор static в объявление константы.
Использование констант в программах обеспечивает, по крайней мере, три преимущества:
Константы облегчают чтение программ, заменяя "магические" числа и строки читаемыми именами, назначение которых легко понять.
Константы облегчают модификацию программ. Например, предположим, что в программе С# имеется константа SalesTax (налог с продаж), которой присвоено значение 6 процентов. Если налог с продаж когда-нибудь изменится, вы можете модифицировать все вычисления налога, просто присвоив новое значение этой константе, и не понадобится просматривать код в поисках значений О.О6 изменять каждое из них, надеясь, что оно нигде не будет пропущено.
Константы позволяют избежать ошибок в программах. Если попытаться присвоить новое значение константе где-то в другом месте программы, а не там, где она объявлена, компилятор выдаст сообщение об ошибке.
Модификаторы доступа
Модификаторы доступа – это ключевые слова, задающие объявленную доступность члена или типа. В этой главе описано четыре модификатора доступа.
public
Ключевое слово public является модификатором доступа для типов и членов типов. Общий (public) доступ является уровнем доступа с максимальными правами. Ограничений доступа к общим членам не существует, как показано в следующем примере:
Копировать
class SampleClass
{
public int x; // No access restrictions.
}
Дополнительные сведения см. в разделах Модификаторы доступа (Руководство по программированию в C#) и Уровни доступности (Справочник по C#).
Пример
В следующем примере объявляются два класса: PointTest и MainClass. Доступ к общим членам x и y класса PointTest осуществляется непосредственно из класса MainClass.
C#
Копировать
class PointTest
{
public int x;
public int y;
}
class MainClass4
{
static void Main()
{
PointTest p = new PointTest();
// Direct access to public members:
p.x = 10;
p.y = 15;
Console.WriteLine("x = {0}, y = {1}", p.x, p.y);
}
}
// Output: x = 10, y = 15
Если уровень доступа public изменить на private или protected, то в результате будет выводиться следующее сообщение об ошибке:
Доступ к элементу "PointTest.y" невозможен из-за его уровня защиты.
protected
Ключевое слово protected является модификатором доступа к члену. Доступ к члену с модификатором protected возможен внутри класса и из производных экземпляров класса. Для сравнения ключевого слова protected с другими модификаторами доступа см. раздел Уровни доступности.
Пример
Член базового класса с модификатором protected доступен в производном классе только в том случае, если доступ осуществляется через тип производного класса. В качестве примера рассмотрим следующий фрагмент кода:
C#
Копировать
class A
{
protected int x = 123;
}
class B : A
{
static void Main()
{
A a = new A();
B b = new B();
// Error CS1540, because x can only be accessed by
// classes derived from A.
// a.x = 10;
// OK, because this class derives from A.
b.x = 10;
}
}
Оператор a.x = 10 генерирует ошибку, поскольку он произведен внутри статического метода Main, а не внутри экземпляра класса B.
Элементы структур не могут использоваться с модификатором protected, потому что наследование от структуры невозможно.
В этом примере класс DerivedPoint является производным от класса Point. Следовательно, доступ к членам базового класса с модификатором protected можно осуществлять непосредственно из производного класса.
C#
Копировать
class Point
{
protected int x;
protected int y;
}
class DerivedPoint: Point
{
static void Main()
{
DerivedPoint dpoint = new DerivedPoint();
// Direct access to protected members:
dpoint.x = 10;
dpoint.y = 15;
Console.WriteLine("x = {0}, y = {1}", dpoint.x, dpoint.y);
}
}
// Output: x = 10, y = 15
Если изменить уровень доступа к переменным x и y на private, то компилятор выдаст следующие сообщения об ошибке:
'Point.y' is inaccessible due to its protection level.
'Point.x' is inaccessible due to its protection level.
internal
Ключевое слово internalмодификатор доступа для типов и членов типов. Внутренние типы или члены доступны только внутри файлов в одной и той же сборке (см. следующий пример).
Копировать
public class BaseClass
{
// Only accessible within the same assembly
internal static int x = 0;
}
Доступ к типам или членам с модификатором доступа protected internal может осуществляться из текущей сборки или из типов, которые являются производными от содержащего их класса.
Сравнение модификатора internal с другими модификаторами доступа см. в разделах Уровни доступности (Справочник по C#) и Модификаторы доступа (Руководство по программированию в C#).
Дополнительные сведения о сборках см. в разделе Сборки и глобальный кэш сборок (C# и Visual Basic).
Внутренний доступ чаще всего используется в разработке на основе компонентов, так как он позволяет группе компонентов взаимодействовать в закрытой форме, не открывая доступ остальной части кода приложения. Например, структура для построения графических пользовательских интерфейсов может предоставлять классы Control и Form, взаимодействующие при помощи членов с внутренним доступом. Так как эти члены являются закрытыми, они не предоставляются коду, использующему структуру.
Создание ссылки на тип или член с внутренним доступом за пределами сборки, в которой он был определен, приведет к ошибке.
Пример
В этом примере содержится два файла: Assembly1.cs и Assembly1_a.cs. Первый файл содержит внутренний базовый класс BaseClass. Попытка создания экземпляра BaseClass во втором файле приведет к ошибке.
Копировать
// Assembly1.cs
// Compile with: /target:library
internal class BaseClass
{
public static int intM = 0;
}
Копировать
// Assembly1_a.cs
// Compile with: /reference:Assembly1.dll
class TestAccess
{
static void Main()
{
BaseClass myBase = new BaseClass(); // CS0122
}
}
В этом примере используются те же файлы, что и в примере 1, но уровень доступности BaseClass изменен на public. Кроме того, уровень доступности члена IntM изменен на internal. В этом случае можно создать экземпляр класса, но доступ к внутреннему члену отсутствует.
Копировать
// Assembly2.cs
// Compile with: /target:library
public class BaseClass
{
internal static int intM = 0;
}
Копировать
// Assembly2_a.cs
// Compile with: /reference:Assembly1.dll
public class TestAccess
{
static void Main()
{
BaseClass myBase = new BaseClass(); // Ok.
BaseClass.intM = 444; // CS0117
}
}
private
Ключевое слово private является модификатором доступа к члену. Закрытый (private) доступ является уровнем доступа с минимальными правами. Доступ к закрытым членам можно получить только внутри тела класса или структуры, в которой они объявлены, как показано в следующем примере:
Копировать
class Employee
{
private int i;
double d; // private access by default
}
Вложенные типы в том же теле могут также обращаться к таким закрытым членам.
Ошибка времени компиляции возникнет в том случае, если создать ссылку на закрытый член за пределами класса или структуры, в которой он объявлен.
Сравнение модификатора private с другими модификаторами доступа см. в разделах Уровни доступности (Справочник по C#) и Модификаторы доступа (Руководство по программированию в C#).
Пример
В этом примере класс Employee содержит два закрытых элемента данных – name и salary. Как к закрытым членам, к ним нельзя получить доступ кроме как через методы членов. Для получения управляемого доступа к закрытым членам можно использовать методы с именем GetName и Salary. Доступ к методу name можно получить через открытый метод, а к методу salary – через открытое свойство только для чтения. (Дополнительные сведения см. в разделе Свойства (Руководство по программированию в C#).)
C#
Копировать
class Employee2
{
private string name = "FirstName, LastName";
private double salary = 100.0;
public string GetName()
{
return name;
}
public double Salary
{
get { return salary; }
}
}
class PrivateTest
{
static void Main()
{
Employee2 e = new Employee2();
// The data members are inaccessible (private), so
// they can't be accessed like this:
// string n = e.name;
// double s = e.salary;
// 'name' is indirectly accessed via method:
string n = e.GetName();
// 'salary' is indirectly accessed via property
double s = e.Salary;
}
}
При помощи модификаторов доступа можно задать следующие пять уровней доступности:
public : Неограниченный доступ.
protected : Доступ ограничен содержащим классом или типами, которые являются производными от содержащего класса.
Internal : Доступ ограничен текущей сборкой.
protected internal: Доступ ограничен пределами сборки или типа, который является производным от данного класса.
private : Доступ ограничен содержащим типом.
