- •Вопрос 1. Общее понятие ооп
- •Вопрос 2. Классы, объекты, абстрагирование
- •Вопрос 3. Полиморфизм, инкапсуляция, наследование
- •Вопрос4. История развития и базовый синтаксис с#
- •Вопрос 5. Основные черты языка с#
- •Вопрос 6. Система типов с#
- •Вопрос 7. Литералы, переменные, константы, перечисления Литералы. Представление значений
- •Переменные элементарных типов. Объявление и инициализация
- •Константы
- •Перечисления
- •Вопрос 8. Операции и выражения
- •Приоритет операций
- •Вопрос 9. Приведение типов
- •Вопрос 10 Контроль за перевыполнением
- •Вопрос 11 Процедурные и функциональные методы в с#
- •Вопрос 11 Создание и уничтожение объектов
- •Модификатор static и объект this Кроме выше рассмотренных модификаторов доступа (public,protected…) в языке c# существует еще ряд модификаторов. Один из них – модификатор static.
- •Уничтожение объектов в управляемой памяти. Деструктор
- •Вопрос 13 Параметризованные классы и индексаторы
- •Параметризованные классы – классы, позволяющие определить тип своих аргументов при непосредственном создании объектов.
- •Вопрос 14 управляющие операторы
- •Вопрос 15 массивы
- •Вопрос 16 перегрузка операций
- •Вопрос 17 Наследование. Конструкторы базового и производного классов
- •Вопрос 18 Переопределение членов базового класса:new модификатор
- •Вопрос 19 Прекращение наследования: sealed-спецификатор
- •Вопрос 20 Абстрактные функции и абстрактные классы
- •Вопрос 21 Операции is и as
- •Вопрос 22 Ввод и вывод данных с#
- •Потоки: байтовые, символьные, двоичные
- •Консольный ввод/вывод. Функции – члены класса Console
- •Консольный вывод. Форматирование
- •Нестандартное (custom) форматирование значений
- •Консольный ввод. Преобразование значений
Вопрос 15 массивы
Массив – упорядоченное множество однотипных элементов. Это тоже ТИП.
Одной из характеристик массива является ранг или размерность массива. Массив размерности (или ранга) N (N определяет число измерений массива) – это Массив массивов (или составляющих массива) ранга N–1. Составляющие массива – это массивы меньшей размерности, являющиеся элементами данного массива. При этом составляющая массива сама может быть либо массивом, либо элементом массива. Объявление массива:
ДВЕ различных категории массивов:
простые (прямоугольные) массивы,
jagged (вложенные) массивы.
Массив мало объявить, его нужно еще проинициализировать. Только тогда ранее специфицированное множество однотипных объектов будет размещено в памяти.
int[] myArray = new int [5];
Операция new используется для создания массива и инициализации его элементов предопределенными значениями. В результате выполнения этого оператора все элементы массива будут установлены в ноль.
Вопрос 16 перегрузка операций
Перегрузка операций в C# является способом объявления семантики новых операций, которые обозначаются принятыми в C# символами операций.
Перегрузка операций строится на основе общедоступных (public) статических (вызываемых от имени класса) функций-членов с использованием ключевого слова operator.
Не все операции множества могут быть переопределены (перегружены) подобным образом. Некоторые операции могут перегружаться с ограничениями.
В таблице приводится соответствующая информация относительно перегрузки различных категорий символов операций.
+, –, !, ~, ++, ––, true, false |
Унарные символы операций, допускающие перегрузку. true и false также являются операциями |
+, –, *, /, %, &, |, ^, <<, >> |
Бинарные символы операций, допускающие перегрузку |
==, !=, <, >, <=, >= |
Операции сравнения перегружаются |
&&, || |
Условные логические операции моделируются с использованием ранее переопределенных операций & и | |
[] |
Операции доступа к элементам массивов моделируются за счет индексаторов |
+=, –=, *=, /=, %=, &=, =, ^=, <<=, >>= |
Операции не перегружаются, по причине невозможности перегрузки операции присвоения |
=, ., ?:, –>, new, is, sizeof, typeof |
Операции, не подлежащие перегрузке |
При этом при перегрузке операций для любого нового типа выполняются следующие правила:
префиксные операции ++ и –– перегружаются парами;
операции сравнения перегружаются парами: если перегружается операция ==, также должна перегружаться операция !=. То же самое относится к парам < и >, <= и >=.
Вопрос 17 Наследование. Конструкторы базового и производного классов
Наследование является одним из принципов ООП. С помощью него реализуются основы классификации, а так же механизмы повторного использования и модификации кода. Базовый класс задает общие признаки и общее поведение для классов-наследников. То есть общие (наиболее общие) свойства и методы наследуются от базового класса, но в дополнение к ним добавляются и определяются НОВЫЕ свойства и методы. Таким образом, прежде всего наследование реализует механизмы расширения базового класса.
Производный класс наследует от базового класса ВСЕ, что он имеет. Другое дело, что воспользоваться в производном классе можно не всем наследством. Например, объект класса наследника в принципе НЕ может получить доступ к private данным — членам и функциям — членам класса-родителя. Косвенное влияние на такие данные-члены и функции — члены – лишь через public-функции класса-родителя. Следует иметь в виду еще одно важное обстоятельство. Если упорядочить все (известные) спецификаторы доступа C# по степени их открытости: public…private, то наследуемый класс не может иметь более открытый спецификатор доступа, чем его предок.
Спецификатор доступа – protected обеспечивает открытый доступ к членам базового класса, но только для производного класса. Защищенные члены базового класса доступны для ВСЕХ прямых и косвенных наследников данного класса.
При определении классов спецификаторы доступа действуют и в рамках пространства имен. Но в пространстве имен явным образом можно использовать лишь один спецификатор – спецификатор public, либо не использовать никаких спецификаторов.
При создании любого класса, как правило, проектируется его конструктор. Передача управления конструктору базового класса при создании объекта — представителя производного класса осуществляется посредством конструкции ...(...):base(...){...}, которая располагается в объявлении конструктора класса-наследника между заголовком конструктора и телом. После ключевого слова base в скобках располагается список значений параметров конструктора базового класса. Очевидно, что выбор соответствующего конструктора определяется типом значений в списке (возможно, пустом) параметров.
Пример работы с конструкторами:
Построим два новых класса:
class X
{
}
class Y:X
{
}
// Это уже в Main()
Y y = new Y();
Вся работа по созданию объекта – представителя класса Y при явном отсутствии конструкторов по умолчанию возлагается на КОНСТРУКТОРЫ УМОЛЧАНИЯ – те самые, которые самостоятельно строит транслятор.
Особых проблем не будет, если в производном классе явным образом начать объявлять конструкторы:
class X
{
}
class Y:X
{
public Y(int key){}
public Y(){}
}
// Это уже в Main()
Y y0 = new Y();
Y y1 = new Y(125);
С этого момента в производном классе нет больше конструктора умолчания. Теперь все зависит от соответствия оператора определения объекта построенному нами конструктору.
Объявим в производном классе оба варианта конструкторов. И опять все хорошо. Конструктор умолчания базового класса (тот, который строится транслятором) продолжает исправно выполнять свою работу.
Проблемы в производном классе возникнут, если в базовом классе попытаться объявить вариант конструктора с параметрами:
class X
{
public X(int key){}
}
class Y:X
{
public Y(int key){} // Нет конструктора умолчания базового класса!
public Y(){} // Нет конструктора умолчания базового класса!
}
// Это уже в Main()
Y y0 = new Y();
Y y1 = new Y(125);
И здесь транслятор начнет обижаться на конструкторы производного класса, требуя ЯВНОГО объявления конструктора базового класса БЕЗ параметров. Если вспомнить, что при ЛЮБОМ вмешательстве в дело построения конструкторов транслятор снимает с себя всю ответственность, причина негодования транслятора становится очевидной. Возможны два варианта решения проблемы:
явным образом заставить работать новый конструктор базового класса,
самостоятельно объявить новый вариант конструктора без параметров:
class X
{
public X(){}
public X(int key){}
}
class Y:X
public Y(int key){}
public Y():base(125){}
}
// Это уже в Main()
Y y0 = new Y();
Y y1 = new Y(125);
