
- •Лекции по курсу "Технология программирования" (1-й семестр) Оглавление
- •Технология .Net Предыдущее состояние дел.
- •Главные компоненты платформы .Net (clr, cts и cls)
- •Общеязыковая среда выполнения (clr)
- •О бщая система типов и общеязыковые спецификации (cts и cls)
- •Библиотека базовых классов
- •Роль языка с#
- •Компоновочные блоки
- •Роль метаданных типов .Net
- •Роль манифеста компоновочного блока
- •Общая система типов.
- •Объектно-ориентированное программирование
- •Главные элементы объектно-ориентированного подхода
- •Дополнительные элементы ооп
- •Принципы объектно-ориентированного программирования.
- •Классы Инкапсуляция
- •Объект (экземпляр класса).
- •Ключевое слово this
- •Отношения между объектами.
- •Основные отличительные особенности класса
- •Спецификаторы доступа
- •Состав класса
- •Поля класса
- •Доступ к полям
- •Статические и экземплярные переменные
- •Методы (функции-члены класса)
- •Переменное число параметров метода
- •Статические методы
- •Конструкторы
- •Закрытые конструкторы или классы без экземпляров
- •Статические конструкторы.
- •Деструкторы
- •Абстрактные методы и классы.
- •Свойства
- •Индексаторы
- •Статические классы
- •Частичные классы
- •Рекомендации по программированию
- •Наследование Понятие наследования в программировании
- •Типы наследования
- •Наследование реализации
- •Определение наследующих классов
- •Уровень доступа protected и internal
- •Ссылка на объект базового класса
- •Протоклассы
- •Предотвращение наследования с помощью ключевого слова sealed.
- •Отношения между классами
- •Абстрактные классы.
- •Класс object
- •Функциональные замыкания
- •Разработка функциональных замыканий с помощью наследования
- •Разработка функциональных замыканий с помощью экземпляров класса
- •Заключение.
- •Полиморфизм
- •Полиморфизм наследующих классов.
- •Переопределение методов родительского класса. Раннее связывание.
- •Виртуальные методы и их переопределение.
- •Как вызывают виртуальные методы
- •Виртуальные функции и принцип полиморфизма
- •Перегрузка.
- •Перегруженные конструкторы
- •Рекомендации программисту.
Статические классы
В версию 2.0 введена возможность описывать статический класс, то есть класс с модификатором static. Экземпляры такого класса создавать запрещено, и кроме того, от него запрещено наследовать. Все элементы такого класса должны явным образом объявляться с модификатором static (константы и вложенные типы классифицируются как статические элементы автоматически). Конструктор экземпляра для статического класса задавать, естественно, запрещается.
Для каждого объекта при его создании в памяти выделяется отдельная область, в которой хранятся его данные. Кроме того, в классе могут присутствовать статические элементы, которые существуют в единственном экземпляре для всех объектов класса. Часто статические данные называют данными класса, а остальные - данными экземпляра. Функциональные элементы класса не тиражируются, то есть всегда хранятся в единственном экземпляре для всех экземпляров класса. Для работы с данными класса используются методы класса (статические методы), для работы с данными экземпляра — методы экземпляра, или просто методы.
Частичные классы
С выходом .Net 2.0 в С# появилась новая синтаксическая конструкция – частичные классы. Обычный класс должен быть целиком описан в одном файле, а описание частичного класса может быть разбито по нескольким файлам. Программистам практически не нужна эта возможность – никому не приходит в голову разбивать описание по нескольким файлам. Однако это очень удобно, когда программист использует какое-нибудь инструментальное средство для генерации части кода. Например, дизайнер Windows Forms автоматически создает код, описывающий содержимое формы. В Visual Studio 2003 он записывал этот код в тот же самый файл, в котором программист описывал логику работы приложения. В Visual Studio 2005 этот код пишется уже в отдельный файл, и вероятность того, что программист случайно повредит его, становится минимальной.
По аналогии можно предположить, что частичные методы тоже можно описывать в двух файлах – половину в одном, а половину в другом. Но на самом деле это не так. Частичные методы устроены совершенно иначе, чем частичные классы. Частичные методы могут использоваться только внутри частичных классов. Отсюда они вероятно и получили свое название. Один из файлов, в которых описывается класс, должен содержать описание метода – название, тип возвращаемого значения и список параметров, но без тела метода, например, вот так:
partial class PartialMethodSample
{
partial void PrintMessage(string msg);
public void Connect()
{
PrintMessage("Connecting");
// Здесь должен быть код, выполняющий соединение с базой данных
PrintMessage("Connected");
}
}
Ну и зачем нам нужно ключевое слово "partial"? – спросите вы. Все это можно было бы сделать и раньше, да к тому же не нужно было заранее объявлять метод в первом файле! Все дело в том, что у частичного метода тела может и не быть. Даже если я целиком уберу второй файл, проект все равно будет отлично компилироваться. Но как же так? Получается, что мы вызываем метод, у которого нет тела! Но это же бессмысленно!
Дело в том, что если компилятор обнаруживает вызов частичного метода, для которого отсутствует тело, а есть только описание сигнатуры, он просто пропускает этот вызов и не компилирует его. Так, как если бы вызова этого метода вообще бы не было. Такое поведение кажется странным, но давайте вспомним, зачем были придуманы частичные классы. Для удобства автоматической генерации кода. И частичные методы нужны для того же самого. Предположим, что первый файл сгенерировал какой-нибудь мастер или визуальный редактор. Он не знает, нужно ли выводить сообщения, а если и нужно, то куда: в консоль, в базу данных или каждое из них нужно показать отдельным окошком. Тем не менее, наш мастер создает частичный метод, использует его в своем коде, но тела не определяет. Предполагается, что программист, использующий этот автоматически сгенерированный класс, просто создаст дополнительный файл, в котором укажет, куда и как выводить сообщения. В нашем примере – на консоль.
Таким образом:
Разделение классов (partial types) - это возможность разделять код класса на несколько частей.
Эта возможность очень полезна, если
класс очень велик
над одним классам параллельно должны работать несколько программистов
часть класса генерируется некоторым генератором исходного кода (например, дизайнером форм/компонентов), а часть пишется вручную программистом
Пример:
public class User
{
private int mInt;
private long mLong;
private string mString;
private bool mBool;
public int MyInt
{
get{ return this.mInt; }
set{ this.mInt = value; }
}
}
Пример разделенного класса:
public partial class User
{
private int mInt;
private long mLong;
private string mString;
private bool mBool;
}
public partial class User
{
public int MyInt
{
get{return this.mInt;}
set{this.mInt = value;}
}
}
Резюме:
Эти два способа равнозначны.
Части класса могут находиться в одном или разных файлах (но вряд ли этому может найтись применение)
Использование возможности разделения классов предоставляет следующие возможности:
Разделять функции класса по нескольким файлам, что позволит одновременно работать с разными частями класса нескольким разработчикам.
Отделить код создаваемый генератором кода и разработчиком, как например это сделано для поддержки дизайнера форм в Visual Studio 2005. Там код располагающий элементы на форме по умолчанию скрыт и отделен от код написанного программистом с использованием ключевого слова partial.