Основные конструкции языка программирования


Теоретические основы программирования

В этом разделе я хочу сделать обзор основных конструкций языка программирования. Сразу стоит отметить, что речь будет идти только о процедурном программировании. Процедурное (императивное) программирование - это всегда описание порядка действий, которые необходимо выполнить вычислительной машине, чтобы достичь требуемого результата. Есть еще и непроцедурное (декларативное) программирование, к которому относят функциональное и логическое описание решения задачи. Функциональное программирование основано на композиции и суперпозиции функций – декларативном описании всего решения или отдельного его шага. Декларативное программирование, в отличие от императивного, не описывает то, в каком порядке следует выполнять вычисления, а именно "декларирует" то, какие вычисления необходимы в принципе. Примером декларативного языка программирования можно назвать язык запросов к базе данных SQL: вы формулируете только суть запроса: указываете, какие данные выбрать, откуда их взять и какие критерии отбора использовать, но сам процесс обработки запроса вы не контролируете. Логическое программирование, в свою очередь, сводится к определению логических взаимосвязей между структурами данных и исчислению предикатов. Наиболее известным логическим языком программирования является Prolog. Ни примеров, ни описаний из разряда “как работает” непроцедурное программирование здесь приведено не будет.

Помимо перечня основных конструкций процедурного программирования, их краткого описания и представления с использованием псевдокода и блок-схем, я постараюсь привести их воплощения на наиболее популярных языках программирования, таких как C/C++, C#, Java, Pascal/Delphi, Visual Basic/VB.NET.


Выражения
Математические выражения
Логические выражения
Строковые выражения
Операторы
Составной оператор
Объявление переменных
Оператор присваивания
Условный оператор или оператор IF
Оператор выбора или оператор SELECT (SWITCH)
Цикл с определенным количеством итераций или цикл FOR
Цикл с предусловием или цикл WHILE
Цикл с постусловием или цикл DO (UNTIL)
Цикл перебора элементов в коллекции или цикл FOR EACH
Выход из подпрограммы или оператор RETURN/EXIT
Выход из составного оператора или операторы BREAK и CONTINUE
Метка и переход к метке или операторы LABEL и GOTO
Обработчик исключительной ситуации
Подпрограммы
Процедура
Функция
Типы данных
Элементарные (базовые) типы
Структура
Класс
Интерфейс
Шаблон


Выражения

Выражения не являются самостоятельными конструкциями языка программирования. Чаще всего, они являются аргументами оператора присваивания, условного оператора или цикла.


Математическое выражение

Назначение:
Описание выражения, результатом которого является числовое значение. В состав математического выражения могут входить константы (конкретные числовые значения), переменные элементарных типов и функции. Практически все языки программирования поддерживают основные математические операции: +(сложение),-(вычитание),*(умножение),/(деление). Некоторые также поддерживают на базовом уровне возведение в степень (^), остаток от деления и другие. Более сложные операции доступны, как правило, в виде встроенных функций, например, sqrt(x) – квадратный корень или exp(x) – значение экспоненты. Естественно, что синтаксис математических выражений поддерживает скобки и унарный минус.

Пример математического выражения:
(вычисление длины стороны треугольника по теореме косинусов)

SQRT(B^2 + C^2 - 2*B*C*COS(alpha))


Логическое выражение

Назначение:
Описание выражения, результатом которого является истина (true) или ложь (false). В состав логического выражения также могут входить константы, переменные, функции и скобки. Плюс ко всему, могут использоваться операции сравнения: “больше”, “меньше”, “равно”; и логические операции: “И” (AND), “ИЛИ” (OR) и “НЕ” (NOT).

Пример логического выражения:
(условие существования решения квадратного уравнения)

(A=0) ИЛИ (C=0) ИЛИ ((B^2-4*A*C)>=0)

C/C++,C#, Java
(A==0) || (C==0) || ((B*B-4*A*C)>=0)
                                    

Pascal/Delphi, Visual Basic/VB.NET
(A=0) or (C=0) or ((B*B-4*A*C)>=0)


Строковое выражение

Назначение:
Манипуляция со строками. По виду напоминает математическое выражение, но результатом его является новая строка. Операция +(сложение) в контексте строкового выражения означает объединение (конкатенацию) двух и более строк.


Операторы

Оператор – это основная конструкция в языке программирования, которая представляет собой команду вычислительной машине выполнить некоторое действие или организует выполнение других операторов в определенном порядке.


Составной оператор

Назначение
Организация других операторов в последовательность – конструкция следования.

Блок-схема конструкции следования
Блок-схема конструкции следования.

Псевдокод:
Начало
 Список операторов
Конец

В языках C/C++, C# и Java составной оператор заключается в фигурные скобки {}, В языке Pascal/Delphi составной оператор начинается ключевым словом begin и заканчивается ключевым словом end, а в Visual Basic/VB.NET начало и конец составного оператора могут выглядеть по-разному, например If/End If или Sub/End Sub.


Объявление переменной

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

Псевдокод:

[КОНСТАНТА] имя_типа Имя_переменной [={инициализирующее_значение|выражение|функция}]

Примеры определения переменных:
ЦЕЛЫЙ A
СИМВОЛЬНЫЙ C=’А’
КОНСТАНТА ВЕЩЕСТВЕННЫЙ PI= 3.1415926535

C/C++
int A;
char C = 'A';
const double PI = 3.1415926535;
                            

Java
int A;
char C = 'A';
final double PI = 3.1415926535;
                            

Pascal/Delphi
var A: Integer;
var C: char = 'A';
const PI:Double = 3.1415926535;
                            

Visual Basic/VB.NET
Dim A As Integer
Dim C As Char = "A"c
Const PI As Double = 3.1415926535
                            


Оператор присваивания

Назначение:
Изменение значения переменной. Аргументом оператора присваивания может быть математическое, логическое, строковое выражение или функция. Во многих языках программирования оператор присваивания можно совместить с объявлением переменной.

Псевдокод:

Имя переменной = {значение|выражение|функция}

Пример оператора присваивания:
C=SQRT(B^2 + C^2 - 2*B*C*COS(alpha))

С/C++, C#, Java, Visual Basic/VB.NET
C=sqrt(B*B+C*C-2*B*C*cos(alpha));
                            

Pascal/Delphi
C:=sqrt(B*B+C*C-2*B*C*cos(alpha));
                            


Условный оператор или оператор IF

Назначение:
Организация ветвления хода вычислений в зависимости от условия. ЕСЛИ условие истинно, то выполняется основная часть условного оператора ТО. Также есть возможность определить альтернативный ход вычислений ИНАЧЕ, наличие которого не является обязательным.

Блок-схема условного оператора
Блок-схема условного оператора.

Псевдокод:
ЕСЛИ (Логическое выражение)
ТО Составной оператор
[ИНАЧЕ Составной оператор]

Пример условного оператора:
(Решение квадратного уравнения)
ЕСЛИ (b^2 >= 4 * a * c)
   ВЕЩЕСТВЕННЫЙ d = SQRT(b^2 - 4 * a * c)
   ВЕЩЕСТВЕННЫЙ x1 = (-b + d) / (2 * a)
   ВЕЩЕСТВЕННЫЙ x2 = (-b - d) / (2 * a)
ИНАЧЕ
   ВЫВОД('Решения нет!')
КОНЕЦ ЕСЛИ

C/C++, C#, Java
if (b * b >= 4 * a * c)
{
   double d = Sqrt(b * b - 4 * a * c);
   double x1 = (-b + d) / (2 * a);
   double x2 = (-b - d) / (2 * a);
}
else //Решения нет!

Pascal/Delphi
program example;
 var d,x1,x2:double;
begin
 Writeln ("Введите a,b,c:");
 ReadLn (a,b,c); 
 if b * b >= 4 * a * c 
  then
   begin
     d:= Math.Sqrt(b * b - 4 * a * c);
     x1:= (-b + d) / (2 * a);
     x2:= (-b - d) / (2 * a);
   end 
  else Writeln("Решения нет!");
end;

Visual Basic/VB.NET
Sub example()
    If b * b >= 4 * a * c Then
        Dim d As Double = Math.Sqrt(b * b - 4 * a * c)
        Dim x1 As Double = (-b + d) / (2 * a)
        Dim x2 As Double = (-b - d) / (2 * a)
    Else 'Решения нет!
    End If
End Sub


Оператор выбора или оператор SELECT (SWITCH)

Назначение:
Организация ветвления хода вычислений в соответствии со значением критерия выбора. Оператор выбора предполагает передачу управления одному из вариантов выбора, с которым ассоциировано значение, равное заданному критерию.

Псевдокод:

ВЫБОР (Критерий)
ВАРИАНТ Значение 1: Составной оператор
ВАРИАНТ Значение 2: Составной оператор
…
ВАРИАНТ Значение N: Составной оператор
[ИНАЧЕ: Составной оператор]

Пример:
ВЫБОР (Key)
ВАРИАНТ 1: Вывод("1")
ВАРИАНТ 2: Вывод("2")
ИНАЧЕ: Вывод("Key<>1 И Key<>2")

C/C++, C#, Java
switch (key)
{
   case 1://key == 1
          break;
   case 2://key == 2
          break;
   default://key != 1 && key != 2
          break;
}

Pascal/Delphi
Case key of
   1:  WriteLn("1");
   2:  WriteLn("2");
  Else WriteLn("key<>1 and key<>2");

Visual Basic/VB.NET
Select Case key
  Case 1 '1
  Case 2 '2
  Case Else 'key<>1 and key<>2
End Select


Цикл с определенным количеством итераций или цикл FOR

Назначение:
Организация определенного заголовком цикла числа итераций. Чаще все число итераций задается начальным и конечным значением счетчика цикла и шагом его изменения с каждой итерацией. Счетчик цикла – числовая переменная, значение которой может использоваться в теле цикла, например, в качестве индекса текущего элемента в массиве в задачах последовательной обработки массивов. Явное определение величины шага обязательным не является. Значением шага по умолчанию, обычно, является единица.

Блок-схема цикла FOR
Блок-схема цикла FOR.


Псевдокод:
ЦИКЛ Счетчик={Начальное значение|Математическое выражение} ДО {Конечное значение|Математическое выражение} [ШАГ {Величина шага|Математическое выражение}]
Составной оператор
СЛЕДУЮЩЕЕ ЗНАЧЕНИЕ

Пример:
(Вычисление факториала числа N)
ЦЕЛЫЙ N=10
ЦЕЛЫЙ F=1
ЦИКЛ I=2 ДО N
 F=F*I
СЛЕДУЮЩЕЕ ЗНАЧЕНИЕ
            

C/C++, C#, Java
int N=10;
int F=1;
for (int i = 2; i <= N; i++)
    {
     F = F * i;
    }

Pascal/Delphi
program example;
 var N,F,I:Integer;
begin
 Writeln ("Введите N:");
 ReadLn (N); 
 for i:=2 to N do
  begin
   F:=F*I;
  end; 
end;

Visual Basic/VB.NET
Dim N As Integer = 10
Dim F As Integer = 1
For I As Integer = 2 To N
    F = F * I
Next


Цикл с предусловием или цикл WHILE

Назначение:
Организация повторения (зацикливания) определенной части программы. Условием выполнения тела цикла является истинность заданного логического выражения. Цикл с предусловием характерен тем, что сначала проверяется логическое выражение и только потом выполняется тело цикла. Таким образом, тело цикла с предусловием имеет все шансы не выполниться ни одного раза.

Блок-схема цикла с предусловием
Блок-схема цикла с предусловием.

Псевдокод:
ПОКА (Логическое выражение)
Составной оператор
КОНЕЦ ЦИКЛА ПОКА

Пример:
(Вычисление факториала числа N)
ЦЕЛЫЙ N=10
ЦЕЛЫЙ F=1
ЦЕЛЫЙ I=1
ПОКА I<N
 I=I+1
 F=F*I
КОНЕЦ ЦИКЛА ПОКА
    

C/C++, C#, Java
int N=10;
int F=1;
int I=1;
while (I<N)
{
  I++;
  F=F*I;
}

Pascal/Delphi
program example;
 var N,F,I:Integer;
begin
 Writeln ("Введите N:");
 ReadLn (N);
 F:=1;
 I:=1; 
 while I<N do
  begin
   I:=I+1; 
   F:=F*I;
  end; 
end;

Visual Basic/VB.NET
Dim N As Integer = 10
Dim F As Integer = 1
Dim I As Integer = 1
While I < N
      I = I + 1
      F = F * I
End While


Цикл с постусловием или цикл DO (UNTIL)

Назначение:
Все аналогично циклу с предусловием с той лишь разницей, что сначала всегда выполняется тело цикла, а потом проверяется условие повторного его выполнения. Цикл с постусловием выполняется минимум один раз! С помощью цикла с постусловием, к примеру, программируют всем известную задачу “угадай число”, критерием завершения цикла в которой является факт совпадения введенного пользователем варианта с “загаданным” машиной значением. Существует две разновидности цикла с постусловием: цикл выполняется ПОКА условие истинно или цикл выполняется ПОКА НЕ условие истинно, т.е. цикл завершается, как только условие становится истинным и выполняется, пока оно ложно.

Блок-схема цикла с постусловием
Блок-схема цикла с постусловием.

Псевдокод:
ВЫПОЛНЯТЬ
Составной оператор
ПОКА (Логическое выражение)
или
ВЫПОЛНЯТЬ
Составной оператор
ПОКА НЕ(Логическое выражение)

Пример:
(Вычисление факториала числа N)
ЦЕЛЫЙ N=10
ЦЕЛЫЙ F=1
ЦЕЛЫЙ I=1
ВЫПОЛНЯТЬ
 I=I+1
 F=F*I
ПОКА I<N
или
ЦЕЛЫЙ N=10
ЦЕЛЫЙ F=1
ЦЕЛЫЙ I=1
ВЫПОЛНЯТЬ
 I=I+1
 F=F*I
ПОКА НЕ I>=N

C/C++, C#, Java
int N=10;
int F=1;
int I=1;
do
{
  I++;
  F = F * I;
} while (I < N);

Pascal/Delphi
program example;
 var N,F,I:Integer;
begin
 Writeln ("Введите N:");
 ReadLn (N);
 F:=1;
 I:=1; 
 repeat
  I:=I+1; 
  F:=F*I;
 until I>=N 
end;

Visual Basic/VB.NET
Dim N As Integer = 10
Dim F As Integer = 1
Dim I As Integer = 1
Do
    I = I + 1
    F = F * I
Loop While I < N
или
Dim N As Integer = 10
Dim F As Integer = 1
Dim I As Integer = 1
Do
    I = I + 1
    F = F * I
Loop Until I >= N


Цикл перебора элементов в коллекции или цикл FOR EACH

Назначение:
Избавить программиста от самостоятельного перебора элементов в массиве или коллекции. Количество итераций соответствует числу элементов в заданном множестве.

Псевдокод:

ДЛЯ КАЖДОГО тип_элемента имя_элемента ИЗ имя_коллекции
Составной оператор
СЛЕДУЮЩИЙ


Выход из подпрограммы или оператор RETURN/EXIT

Назначение:
Досрочный выход из процедуры или функции. В языках C/C++, C#, Java и VB.NET оператор return в контексте процедуры просто досрочно завершает ее работу, а в контексте функции еще и определяет ее значение: return result_value;. В языках Pascal/Delphi оператор exit просто завершает выполнение и процедуры и функции, а значение функции присваивается по ее имени: function_name:=result_value;.


Выход из составного оператора или операторы BREAK и CONTINUE

Назначение:
Досрочный выход из составного оператора, например, досрочное завершение цикла. В языках C/C++, C#, Java и Pascal/Delphi оператор break позволяет завершить работу текущего цикла или оператора switch. В Visual Basic/VB.NET для этих целей используются инструкции Exit For, Exit While, Exit Do и т.п. В языках C/C++, C#, Java и Pascal есть еще и оператор continue, который в отличие от break не выходит совсем из цикла, а завершает только текущую итерацию, т.е. переходит к анализу заголовка цикла.


Метка и переход к метке или операторы LABEL и GOTO

Назначение:
Выделение определенного места в программе (установка метки) с возможностью безусловного перехода к этой метке из другой части программы. Переход чаще всего возможен только в границах одной процедуры или функции. Есть мнение, что использование меток – это плохой стиль в программировании. Чаще всего оператором безусловного перехода к метке является команда goto.

Псевдокод:
(Пример установки метки и перехода к метке)

Имя_метки: 
…
ПЕРЕХОД Имя_метки

В большинстве языков программирования работа с метками будет выглядеть примерно так:
[label] Имя_метки: 
…
goto Имя_метки


Обработчик исключительной ситуации

Назначение:
Выделение части программного кода, результат выполнения которого потенциально может привести к ошибке или исключительной ситуации с целью контроля над процессом обработки этой ситуации. Примером такой части кода может стать попытка соединения с базой данных. Обработка исключительных ситуаций на языке C# описана здесь.


Декомпозиция программного кода

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


Процедура

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

Псевдокод:

ПРОЦЕДУРА Имя (СПИСОК ПАРАМЕТРОВ)
Составной оператор
[КОНЕЦ ПРОЦЕДУРЫ]

,где СПИСОК ПАРАМЕТРОВ – это список объявлений переменных (для каждого аргумента процедуры), разделенных запятыми.


Функция

Назначение:
Аналогично процедуре с той разницей, что функция возвращает результат определенного для нее типа. Вызов функции может быть не только частью составного оператора, но и аргументом оператора присваивания, частью математического, логического или строкового выражения.

Псевдокод:

ФУНКЦИЯ Имя (СПИСОК ПАРАМЕТРОВ) ТИП
Составной оператор
[КОНЕЦ ФУНКЦИИ]

Посмотреть, как используются функции в процедурном программировании на примере задачи вычисления последовательности простых чисел.


Типы данных

Типы данных – это то, без чего любой вид программирования не возможен в принципе. Эти конструкции предназначены для описания формата обрабатываемой программой информации: от элементарных данных до сложноорганизованных структур.


Элементарные (базовые) типы данных

Назначение:
Описание неделимой части информации, например, числовой переменной, символа или результата логического выражения. Большинство языков программирования поддерживают одни и те же элементарные или базовые типы: целочисленный, вещественный, символьный, логический, дата и время. Диапазон значений для целочисленного и вещественного типа определяется количеством занимаемых им байт. Один байт – это объем информации, способный хранить 256 различных значений и состоящий из 8 бит. Бит, в свою очередь, способен хранить лишь два значения: 0 и 1. Комбинаций из 8 нулей и единиц ровно 256 (2^8). В этом контексте целочисленные и вещественные типы делятся на подтипы, которые в каждом языке программирования могут обозначаться по-разному. Также, к элементарным типам часто относят строковый тип данных (последовательность символов - строка), который неделимым не является, но также относится к базовым типам. Ниже приведена таблица с основными элементарными типами наиболее известных языков программирования.

Описание типаРазмер (биты)Диапазон.NETC#VB.NETC/C++JavaPascal/Delphi
Байт со знаком8от -128 до 127SBytesbyteSBytesigned charbyteshortint
Байт без знака8от 0 до 255BytebyteByteunsigned char-byte
Короткое целое число со знаком16от -32 768 до 32 767Int16shortShortshortshortinteger
Короткое целое число без знака16от 0 до 65 535UInt16ushortUShortunsigned short-word
Среднее целое число со знаком32от -2147483648 до 2147483647Int32intIntegerintintlongint
Среднее целое число без знака32от 0 до 4294967295UInt32uintUIntegerunsigned int--
Длинное целое число со знаком64от -9223372036854775808 до 9223372036854775807Int64longLonglonglong-
Длинное целое число без знака64от 0 до 18446744073709551615UInt64ulongUlongunsigned long--
Вещественное число одинарной точности с плавающей запятой32±1,5*10-45 до ±3,4*1033SinglefloatSinglefloatfloatsingle
Вещественное число двойной точности с плавающей запятой64±5*10-324 до ±1,7*10306DoubledoubleDoubledoubledoubledouble
Символ (8 бит)8ASCII---char-char
Символ (16 бит)16UNICODECharcharCharwchar_tchar-
Логический тип8{true, false}BooleanboolBooleanboolbooleanboolean
Строка--StringstringStringchar*/wchar_t*Stringstring
Пустой тип---void-voidvoid-


Структура

Назначение:
Описание сложных (составных) типов данных. Структура может в себе содержать определения переменных элементарных типов (числовые, символьные, логические), а также определения массивов, коллекций, классов, других структур и т.д. Все составные части структуры называют полями структуры. Экземпляры структур создаются точно так же, как экземпляры простых типов. Доступ к любому полю структуры, как правило, осуществляется по имени соответствующей переменной – экземпляра структуры и имени поля, разделенных между собой точкой. Более подробно про структуры в языке программирования C# вы можете прочитать здесь.

Псевдокод:

СТРУКТУРА Имя
Объявление поля 1
Объявление поля 2
…
Объявление поля N
КОНЕЦ СТРУКТУРЫ


Класс

Назначение:
Класс расширяет возможности структуры тем, что помимо описания составного типа данных (полей класса) позволяет определять программный код для их обработки. Другими словами, класс – это структура плюс набор процедур и функций, непосредственно связанных с обработкой ее полей. Как правило, функции и процедуры класса - методы класса имеют больше прав на редактирование полей, чем любые другие, внешние по отношению к классу части программы. К отдельному виду подпрограмм в контексте класса относят свойства, отвечающие за доступ и изменение значений полей класса. Обычно, свойство – это совокупность процедуры для изменения значения поля и функции для передачи его значения. Синтаксис обращения к свойству класса аналогичен обращению к полю. Если определена только функция, то свойство предназначено только для чтения данных, если определена только процедура – то только для записи. Доступ ко всем членам класса (поля, свойства, методы) задается модификаторами доступа, определяющими: возможно ли обращение к члену из внешней части программы - публичный член (public), или он предназначен для использования только внутри класса - частный член (private). Такое сокрытие деталей реализации класса от внешнего мира называется инкапсуляцией. Экземпляр класса называют объектом. Отсюда и термин: объектно-ориентированное программирование. Также, для классов определена операция наследования: любой класс может наследовать данные и поведение (методы и свойства) любого другого класса, дополняя его своими данными и своим поведением. Класс, который является “наследником” называется производным классом, а класс, который это самое наследство передает – базовым классом. Стоит отметить, что в C#, как классы, так и структуры могут иметь методы и свойства, но наследование определено только для классов. Некоторые языки программирования, такие как C++, допускают множественное наследование – это когда у одного класса может быть несколько базовых классов. Более подробно про наследование в частности и объектно-ориентированное программирование в целом на языке программирования C# можно прочитать здесь.


Интерфейс

Назначение:
Описание поведения класса. Интерфейс содержит описание методов и свойств класса без их реализации: только имена, списки аргументов и типы возвращаемых значений (сигнатуру). Класс, реализующий интерфейс, обязан реализовать все его методы и свойства. Интерфейсы являются ключевой абстракцией в объектно-ориентированном программировании, поскольку с их помощью реализуется полиморфизм объектов. Вы можете организовать унифицированную обработку экземпляров абсолютно разных классов, если все они реализуют общий интерфейс. Пример из жизни людей: паспорт – это основной ваш интерфейс при общении с бюрократами в повседневной жизни. Их в меньшей степени волнует, какой у вас род занятий, ваши увлечения и т.п. Реализуют интерфейс все по-разному (записано в паспорте у всех все разное), но доступ к этой информации единый. Таким образом, полиморфизм – это возможность определить различное поведение объектов разных классов в результате одного и того же воздействия – вызова методов и свойств общего для них интерфейса. Еще один пример, но уже из жизни вещей: все автомобили предоставляют интерфейс “нажатия на педаль газа”, но так же все они ведут себя по-разному, когда на этот газ нажимает водитель, пусть даже с одинаковым усилием. Интерфейс – это не самостоятельный экземпляр типа данных, а ссылка на объект в контексте определенного аспекта его поведения. Любой класс реализует как минимум один интерфейс – основной интерфейс, представленный его собственными методами и свойствами. Более подробно про интерфейсы в контексте языка программирования C# вы можете прочитать здесь. Примеры реализации полиморфизма можно увидеть здесь и здесь.


Шаблон

Назначение:
Создать универсальный тип данных (класс, структуру, интерфейс) или отдельную универсальную подпрограмму (процедуру, функцию) для решения задачи, связанной с общей для различных типов данных логикой их обработки. Такой задачей, к примеру, может быть сортировка последовательности элементов, чей тип заранее неизвестен, но известно то, что для экземпляров данного типа определена операция сравнения. Шаблон – это обобщенное описание решения задачи. Шаблон имеет список типов-параметров, которые в его контексте обозначают любой тип. В терминах этих самых типов-параметров и описывают процесс обработки данных. При создании экземпляра шаблона или вызове подпрограммы-шаблона указывают конкретные значения типов-параметров, и компилятор создает исполняемый код уже в контексте указанных значений типов – формирует реализацию шаблона. На типы-параметры шаблона разные языки программирования позволяют накладывать различного рода ограничения, например, предъявлять требования, чтобы конкретный тип был элементарным типом, структурой или классом. В случае классов бывает возможность дополнительно задать ограничение на поддерживаемые этим классом интерфейсы. Более подробно про шаблоны (универсальные типы) вы можете прочитать здесь.


Начнем начальный практический курс