Редактирование: Сравнение Языков Программирования
Материал из eSyr's wiki.
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
ПРЕДУПРЕЖДЕНИЕ: Длина этой страницы составляет 155 килобайт. Страницы, размер которых приближается к 32 КБ или превышает это значение, могут неверно отображаться в некоторых браузерах. Пожалуйста, рассмотрите вариант разбиения страницы на меньшие части.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
На этой страничке собираются материалы, которые могут помочь при подготовке к экзамену по языкам программирования. | На этой страничке собираются материалы, которые могут помочь при подготовке к экзамену по языкам программирования. | ||
- | ЯП из курса: C, C++, Java, C#, Pascal, Delphi, Оберон-2, Модула-2, Ада (83 и 95 стандарты) | + | ЯП из курса: C, C++, Java, C#, Pascal, Delphi, Оберон-2, Модула-2, Ада (83 и 95 стандарты) |
Полезные ссылки: | Полезные ссылки: | ||
- | * [[w:Сравнение языков программирования|Сравнение ЯП в википедии]] | ||
- | * [http://progopedia.ru/ Энциклопедия языков программирования] | ||
- | * [http://citforum.ru/programming/cpp/aglav.shtml Книжка Страуструпа] | ||
- | * [https://habrahabr.ru/post/161205/ Ликбез по типизации в языках программирования / Хабрахабр] | ||
- | План (краткий, взят из методички Головина, подробный см. в самой [ | + | [http://ru.wikipedia.org/wiki/%D1%F0%E0%E2%ED%E5%ED%E8%E5_%FF%E7%FB%EA%EE%E2_%EF%F0%EE%E3%F0%E0%EC%EC%E8%F0%EE%E2%E0%ED%E8%FF Сравнение ЯП в википедии] |
+ | |||
+ | [http://progopedia.ru/ Энциклопедия языков программирования] | ||
+ | |||
+ | [http://home.perm.ru/strannik/st_txt_prog_02.html/ Немножно рекламное сравнения большинства языков] | ||
+ | |||
+ | [http://citforum.ru/programming/cpp/aglav.shtml Книжка Страуструпа] | ||
+ | |||
+ | План (краткий, взят из методички Головина, подробный см. в самой [http://cmcmsu.no-ip.info/download/pl.exam.variants.pdf методичке]): | ||
== Базисные типы данных в языках программирования: простые и составные типы данных, операции над ними == | == Базисные типы данных в языках программирования: простые и составные типы данных, операции над ними == | ||
Строка 18: | Строка 22: | ||
; Character: Как я понял, существует несколько разновидностей (зависит от размера) и является особым перечислимым типом (Enumeration) | ; Character: Как я понял, существует несколько разновидностей (зависит от размера) и является особым перечислимым типом (Enumeration) | ||
; String: Массив '''Character''' фиксированной длины. Так же есть стандартные пакеты, реализующие строки квазистатической и динамической длины. | ; String: Массив '''Character''' фиксированной длины. Так же есть стандартные пакеты, реализующие строки квазистатической и динамической длины. | ||
- | ; Floating point: Эти типы обычно определяются вручную в виде конструкции, где Num_Digits указывает | + | ; Floating point: Эти типы обычно определяются вручную в виде конструкции, где Num_Digits указывает минимальную (минимально допустимую?) погрешность: |
'''digits''' Num_Digits | '''digits''' Num_Digits | ||
Строка 58: | Строка 62: | ||
Mother: Person_Access := '''new''' Person'(Mothers_First_Name, Mothers_Last_Name); ''-- инициализованно'' | Mother: Person_Access := '''new''' Person'(Mothers_First_Name, Mothers_Last_Name); ''-- инициализованно'' | ||
- | Тип Access - это высокоуровневый указатель, представленный записью с полями. Например, | + | Тип Access - это высокоуровневый указатель, представленный записью с полями. Например, разименовать указатель можно следующим образом: |
Mother.'''all'''.Last_Name = Father.'''all'''.Last_Name ''-- здесь, Mother.'''all''' имеет тип Person; | Mother.'''all'''.Last_Name = Father.'''all'''.Last_Name ''-- здесь, Mother.'''all''' имеет тип Person; | ||
Строка 139: | Строка 143: | ||
Также существует специальный тип null. | Также существует специальный тип null. | ||
- | Объектом в Java считается экземпляр класса или массив. Значением ссылочного типа является ссылка на объект (или специальное значение null). | + | Объектом в Java считается экземпляр класса или массив. Значением ссылочного типа является ссылка на объект (или специальное значение null). Все объекты (включая массивы) обладают методами класса Object (java.lang.Object) (иначе говоря, с т.з. Java-программиста все объекты *наследуют* методы класса Object). Строковые литералы (например, "Hello world!") являются объектами типа String (== экземплярами класса String). |
- | + | ||
- | Все объекты (включая массивы) обладают методами класса Object (java.lang.Object) (иначе говоря, с т. з. Java-программиста все объекты *наследуют* методы класса Object). Строковые литералы (например, "Hello world!") являются объектами типа String ( | + | |
Операции над простыми типами почти идентичны C/C++, однако могут выбрасывать исключения. Конкатенация строк: "Hello " + "world!" (может принимать в качестве одного из аргументов не только строку, но и любой из целых типов). | Операции над простыми типами почти идентичны C/C++, однако могут выбрасывать исключения. Конкатенация строк: "Hello " + "world!" (может принимать в качестве одного из аргументов не только строку, но и любой из целых типов). | ||
Строка 148: | Строка 150: | ||
=== C++ === | === C++ === | ||
- | |||
; Целые типы: | ; Целые типы: | ||
: char - размер как для хранения символа, определяется машиной (обычно байт) | : char - размер как для хранения символа, определяется машиной (обычно байт) | ||
Строка 164: | Строка 165: | ||
sizeof(float) <= sizeof(double) <= sizeof(long double) | sizeof(float) <= sizeof(double) <= sizeof(long double) | ||
- | + | <b>const</b> <тип> <имя_переменной> = <значение>; | |
// Значение переменной не может изменяться после инициализации (инициализация обязательна). | // Значение переменной не может изменяться после инициализации (инициализация обязательна). | ||
Строка 230: | Строка 231: | ||
== Массивы == | == Массивы == | ||
=== Длина массива — статический или динамический атрибут === | === Длина массива — статический или динамический атрибут === | ||
- | + | <b>Си++</b>: длина массива - только статический атрибут. <br> | |
- | + | <b>Оберон</b>, <b>Модула-2</b>: динамический атрибут только для формальных параметров, в остальных случаях - статический. <br> | |
- | + | <b>Ада</b>, <b>Java</b>, <b>C#</b>: может быть и тем и другим. <br> | |
<br> | <br> | ||
- | + | <b>Замечание из методички</b>: <br> | |
в языках Оберон и Модула-2 длина формальных параметров — открытых массивов является динамическим атрибутом. <br> | в языках Оберон и Модула-2 длина формальных параметров — открытых массивов является динамическим атрибутом. <br> | ||
В других случаях длина массива — статический атрибут. <br> | В других случаях длина массива — статический атрибут. <br> | ||
В Аде формальные параметры неограниченных типов-массивов также имеют динамический атрибут-длину (равно как и динамические массивы-локальные переменные). <br> | В Аде формальные параметры неограниченных типов-массивов также имеют динамический атрибут-длину (равно как и динамические массивы-локальные переменные). <br> | ||
<br> | <br> | ||
- | + | <b>Пример</b> динамического массива в языке Java (или C#): | |
void f(int N) { | void f(int N) { | ||
byte [] dynArray = new byte [N]; | byte [] dynArray = new byte [N]; | ||
Строка 322: | Строка 323: | ||
== Преобразование типов == | == Преобразование типов == | ||
=== Явное преобразование типов === | === Явное преобразование типов === | ||
- | Преобразование типов называется | + | Преобразование типов называется <i>явным,</i> если оно указано программистом в исходном коде. |
=== Неявное преобразование типов === | === Неявное преобразование типов === | ||
+ | Преобразование типов называется <i>неявным,</i> если оно не указывается программистом, но, тем не менее, выполняется (в языках со статической типизацией — подставляется на этапе компиляции). В языках <b>Pascal</b>, <b>Delphi</b>, <b>C#</b> и <b>Java</b> неявными могут быть только расширяющие преобразования; в <b>С++</b> — любые преобразования. | ||
- | + | ==== Неявное преобразование для пользовательских классов==== | |
+ | Язык Java запрещает любые неявные преобразования между | ||
+ | объектами классов (исключение составляют только неявные преобразования | ||
+ | к стандартному типу String, разрешенные в некоторых | ||
+ | контекстах). | ||
- | + | Языки C++ и C# разрешают неявные преобразования для классов, | |
- | + | определяемых пользователем. | |
- | + | ||
- | + | ||
- | + | В '''C++''' преобразования определяются специальными функциями-членами: конструкторами преобразования и функциями преобразования. | |
+ | Конструктор преобразования имеет прототип вида | ||
- | В '''C++''' преобразования определяются специальными функциями-членами: конструкторами преобразования и функциями преобразования. Конструктор преобразования имеет прототип вида: | ||
Х(Т) // или Х(Т&) или X (const Т&) | Х(Т) // или Х(Т&) или X (const Т&) | ||
- | Функция преобразования имеет вид | + | Функция преобразования имеет вид |
class X { | class X { | ||
operator Т(); | operator Т(); | ||
}; | }; | ||
- | В языке '''C#''' область применения пользовательских преобразований уже, чем в языке C++. Можно | + | В языке '''C#''' область применения |
- | определять свои преобразования только между двумя классами, нельзя определять преобразования в типы значений или из них. Преобразование из класса X в класс Y реализуется с помощью специального метода — функции преобразования: | + | пользовательских преобразований уже, чем в языке C++. Можно |
+ | определять свои преобразования только между двумя классами, нельзя | ||
+ | определять преобразования в типы значений или из них. | ||
+ | Преобразование из класса X в класс Y реализуется с помощью | ||
+ | специального метода — функции преобразования: | ||
static operator Y (X х) { ... } | static operator Y (X х) { ... } | ||
- | Функция преобразования может быть только статическим методом либо класса х, либо класса Y. Если такая функция преобразования есть, то она вызывается с использованием обычного синтаксиса преобразований: (Y) х. Компилятор вставляет неявное преобразование из X в Y только, если соответствующая функция преобразования снабжена модификатором implicit: | + | Функция преобразования может быть только статическим методом |
+ | либо класса х, либо класса Y. | ||
+ | Если такая функция преобразования есть, то она вызывается с использованием | ||
+ | обычного синтаксиса преобразований: (Y) х. | ||
+ | Компилятор вставляет неявное преобразование из X в Y только, | ||
+ | если соответствующая функция преобразования снабжена модификатором | ||
+ | implicit: | ||
static implicit operator Y (X x) { ... } | static implicit operator Y (X x) { ... } | ||
- | Если же используется модификатор explicit, то функция преобразования может вызываться только явно. По умолчанию принимается модификатор explicit, что снижает вероятность случайной | + | Если же используется модификатор explicit, то функция преобразования |
+ | может вызываться только явно. По умолчанию принимается | ||
+ | модификатор explicit, что снижает вероятность случайной | ||
ошибки. | ошибки. | ||
Строка 392: | Строка 408: | ||
end. | end. | ||
- | === Понятия | + | === Понятия <i>conversion</i> и <i>casting</i> === |
- | В большинстве языков, основанных на базе | + | В большинстве языков, основанных на базе <b>Algol</b> и обладающих механизмом вложенных функций - например, в <b>Ada, Delphi, Modula 2</b> и <b>Pascal,</b> понятия <i>conversion</i> и <i>casting</i> принципиально различны. Понятие <i>conversion</i> относится к явному или неявному изменению значения одного типа данных на значение другого типа данных (например, расширение 16-битного целого до 32-битного). В этом случае, могут измениться требования к объёму выделенной памяти; могут возникнуть потери точности или округления. Понятие <i>casting,</i> напротив, обозначает <i>явное</i> изменение интерпретации <i>последовательности бит.</i> Например, последовательность из 32 бит может быть интерпретирована как целое без знака, как массив из 32 значений типа boolean или как вещественное число c одинарной точностью, соответствующее стандарту IEEE. |
- | В | + | В <b>C-подобных</b> языках, понятием <i>casting</i> обозначается явное приведение типа в независимости от того, является ли оно изменением интерпретации последовательности бит, либо же настоящим преобразованием типа. |
=== Упаковка и распаковка === | === Упаковка и распаковка === | ||
- | Данные понятия определены для языков | + | Данные понятия определены для языков <b>C#</b> и <b>Java.</b> |
- | : | + | : <i>Упаковкой (boxing)</i> называется процесс преобразования значения простого типа значения в экземпляр соответствующего класса-оболочки. |
- | : | + | : <i>Распаковкой (unboxing)</i> называется, очевидно, процесс преобразования экземпляра класса-оболочки в значение соответствующего простого типа. |
- | + | ||
==== C# ==== | ==== C# ==== | ||
- | В | + | В <b>C#</b> упаковка и распаковка выполняются автоматически. |
Пример упаковки и распаковки: | Пример упаковки и распаковки: | ||
Строка 412: | Строка 427: | ||
==== Java ==== | ==== Java ==== | ||
- | В | + | В <b>Java</b> автоупаковка и автораспаковка поддерживаются начиная с J2SE 5.0 (сентябрь 2004 года). |
Пример упаковки и распаковки: | Пример упаковки и распаковки: | ||
Строка 423: | Строка 438: | ||
==== Другие языки ==== | ==== Другие языки ==== | ||
- | В некоторых языках упаковка и распаковка отсутствуют. Например, в | + | В некоторых языках упаковка и распаковка отсутствуют. Например, в <b>Smalltalk</b> любое значение принадлежит некоторому классу (т.е. даже значения простых типов являются экземплярами классов). Немного по другой причине этих операций нет и в <b>JavaScript</b>: в этом языке отсутствует понятие "класс", т.к. он является прототипным. |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
== Операторный базис языков программирования. Управление последовательностью вычислений == | == Операторный базис языков программирования. Управление последовательностью вычислений == | ||
Строка 712: | Строка 718: | ||
== Процедурные абстракции == | == Процедурные абстракции == | ||
- | === Передача параметров в | + | === Передача параметров в подпрограммах === |
- | + | Для каждой подпрограммы указывается набор формальных параметров. Можно рассматривать формальные параметры как локальные | |
- | Для каждой подпрограммы указывается набор формальных параметров. Можно рассматривать формальные параметры как локальные переменные тела подпрограммы. При вызове подпрограммы указывается список фактических параметров. Соответствие между фактическими и формальными параметрами выполняется по позиции в списке: первый фактический параметр соответствует первому формальному параметру и т. д. Такой способ называется | + | переменные тела подпрограммы. При вызове подпрограммы указывается список фактических параметров. Соответствие между фактическими и формальными параметрами |
- | + | выполняется по позиции в списке: первый фактический параметр соответствует первому формальному параметру и т.д. Такой | |
- | + | способ называется <i>позиционным.</i> Язык С#, начиная с версии 4, предусматривает альтернативный — <i>ключевой</i> способ отождествления, в котором используются имена формальных параметров, но мы не будем его рассматривать.Существует три вида формальных параметров: | |
- | + | : • входные параметры (параметры, от которых требуется только значение). Мы используем только значения фактических параметров, которые не меняются при : : выходе из тела функции; | |
- | + | : • выходные параметры (эти параметры не обязаны иметь начальное значение, но могут быть изменены в теле функции); | |
- | С входным параметром может связываться произвольное выражение, а выходным или изменяемым — только объекты, которые могут стоять в левой части оператора присваивания. В большинстве языков программирования вместо указания вида параметра указывается способ (механизм) связывания параметра, называемый способом передачи параметра. | + | : • изменяемые параметры (требуется и исходное значение, и возможность его изменения). |
- | + | С входным параметром может связываться произвольное выражение, а выходным или изменяемым — только объекты, которые могут стоять в левой части оператора присваивания. В большинстве языков программирования вместо указания вида параметра указывается способ (механизм) связывания параметра, | |
- | Существует два основных способа передачи параметров: | + | называемый способом передачи параметра. |
- | + | Существует два основных способа передачи параметров: <i>по значению</i> и <i>по ссылке.</i> | |
==== Передача параметров по значению ==== | ==== Передача параметров по значению ==== | ||
- | + | Формальный параметр есть некоторая локальная переменная. Место для локальных переменных отводится в стеке. При вызове подпрограммы значение | |
- | Формальный параметр есть некоторая локальная переменная. Место для локальных переменных отводится в стеке. При вызове подпрограммы значение фактического параметра копируется в соответствующий формальный параметр. Все изменения формального параметра связаны с изменением локальной переменной и не сказываются на фактическом параметре. Перед копированием может потребоваться приведение типа, если типы фактического и формального параметров не совпадают. | + | фактического параметра копируется в соответствующий формальный параметр. Все изменения формального параметра связаны с изменением локальной переменной и не сказываются на фактическом параметре. Перед копированием может потребоваться приведение типа, если типы фактического и формального |
- | + | параметров не совпадают. | |
==== Передача параметров по ссылке ==== | ==== Передача параметров по ссылке ==== | ||
- | + | Фактически этот способ есть передача ссылки по значению. Формальный параметр — это ссылка на объект. В момент вызова происходит инициализация ссылки | |
- | Фактически этот способ есть передача ссылки по значению. Формальный параметр — это ссылка на объект. | + | фактическим параметром. Преобразования типов в этот момент не происходит: типы формального и фактического параметров должны совпадать. Поскольку ссылка после инициализации отождествляется с объектом, то любые изменения формального параметра подразумевают изменения фактического параметра. |
- | + | Очевидно, что способ передачи по значению соответствует семантике | |
- | + | входных формальных параметров. | |
- | + | По ссылке можно передавать выходные и изменяемые параметры. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
=== Перегрузка операций === | === Перегрузка операций === | ||
Ада 83, Ада 95, Си++, Java, Delphi, C# | Ада 83, Ада 95, Си++, Java, Delphi, C# | ||
Строка 928: | Строка 920: | ||
==== Деструкторы и финализаторы ==== | ==== Деструкторы и финализаторы ==== | ||
- | Деструкторы и финализаторы — это специальные функции-члены класса, автоматически вызываемые при уничтожении объекта класса. Роль деструкторов и финализаторов — освобождение захваченных объектом ресурсов. Если объект не захватывает ресурсы или ресурсы освобождаются автоматически, то нужды в деструкторе (финализаторе) нет. Деструкторы | + | Деструкторы и финализаторы — это специальные функции-члены класса, автоматически вызываемые при уничтожении объекта класса. Роль деструкторов и финализаторов — освобождение захваченных объектом ресурсов. Если объект не захватывает ресурсы или ресурсы освобождаются автоматически, то нужды в деструкторе (финализаторе) нет. Деструкторы <i>не имеют</i> параметров. В языке Java деструкторов нет, их роль (до определенной степени) |
- | играет метод void finalize() — финализатор. В языке | + | играет метод void finalize() — финализатор. В языке <b>C#</b> формально деструкторы есть, однако их поведение аналогично поведению финализаторов |
- | в языке | + | в языке <b>Java</b>. |
- | Деструкторы в | + | Деструкторы в <b>C++</b> отличаются от финализаторов в <b>Java</b> и <b>C#</b> тем, что в <b>C++</b> можно достаточно точно установить момент вызова деструктора. |
# Деструкторы статических объектов вызываются после выхода из функции main. | # Деструкторы статических объектов вызываются после выхода из функции main. | ||
# Деструкторы квазистатических объектов выполняются при выходе из блока. Причём, деструкторы вызываются строго в обратном порядке относительно порядка вызова конструкторов квазистатических объектов данного блока. | # Деструкторы квазистатических объектов выполняются при выходе из блока. Причём, деструкторы вызываются строго в обратном порядке относительно порядка вызова конструкторов квазистатических объектов данного блока. | ||
# Деструкторы динамических объектов выполняются при вызове операции delete. | # Деструкторы динамических объектов выполняются при вызове операции delete. | ||
# Деструкторы временных объектов выполняются при выходе из конструкции, в контексте которой был создан объект. | # Деструкторы временных объектов выполняются при выходе из конструкции, в контексте которой был создан объект. | ||
- | В | + | В <b>Java</b> и <b>C#</b> время вызова финализатора не определено из-за наличия сборщика мусора. |
Как и конструкторы, деструкторы имеют пользовательскую и системную части. | Как и конструкторы, деструкторы имеют пользовательскую и системную части. | ||
Строка 998: | Строка 990: | ||
FMyField := Value; | FMyField := Value; | ||
end; | end; | ||
- | |||
==== Статические классы ==== | ==== Статические классы ==== | ||
- | + | Под <i>статическим классом</i> понимается разновидность класса, все члены которого объявлены статическими. Как правило, у таких классов не описаны конструктор и деструктор. Использовать статические члены класса можно не создавая самого экземпляра класса. Понятие статического класса чаще всего используется в языках <b>C#</b> и <b>Java.</b> В этих языках невозможно создать экземпляр статического класса; также статический класс не может реализовывать интерфейсы. В <b>C#</b> любой статический класс наследуется от типа object. В <b>С++</b> понятие статического класса как таковое отсутствует. Имитировать статический класс можно либо создав класс, все члены которого объявлены статическими, и запретив создание его экземпляров с помощью модификатора доступа private перед конструктором; либо используя шаблон проектирования singleton - в таком случае, будет существовать <i>ровно один</i> экземпляр данного класса, и будет предоставлена глобальная точка доступа к данному экземпляру. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
=== Объединение типов (запись с вариантами) === | === Объединение типов (запись с вариантами) === | ||
Строка 1072: | Строка 1002: | ||
Проблема копирования состоит в том, что копируемый объект может содержать ссылки на другие объекты. Проблема копирования состоит в том, что объекты могут содержать ссылки на другие объекты. При копировании таких ссылок возникает дилемма: копировать либо только ссылку, либо полностью | Проблема копирования состоит в том, что копируемый объект может содержать ссылки на другие объекты. Проблема копирования состоит в том, что объекты могут содержать ссылки на другие объекты. При копировании таких ссылок возникает дилемма: копировать либо только ссылку, либо полностью | ||
- | содержимое объекта, на который указывает ссылка. Первый вид копирования называется | + | содержимое объекта, на который указывает ссылка. Первый вид копирования называется <i>поверхностным</i>, а второй — <i>глубоким.</i> В общем случае транслятор не в состоянии выбрать нужную семантику копирования, поэтому в языках программирования, которые мы рассматриваем, принята следующая схема: по умолчанию реализуется <i>поверхностное копирование,</i> но программисту предоставляются средства для указания <i>глубокой семантики копирования.</i> В <b>C++</b> этими средствами являются переопределение конструктора копирования и операции присваивания, в <b>Java</b> и <b>C#</b> — наследование и реализация специального интерфейса. |
==== Особенности копирования объектов в Java ==== | ==== Особенности копирования объектов в Java ==== | ||
Строка 1089: | Строка 1019: | ||
* http://docs.oracle.com/javase/7/docs/api/java/lang/CloneNotSupportedException.html | * http://docs.oracle.com/javase/7/docs/api/java/lang/CloneNotSupportedException.html | ||
- | + | В общем случае всё это говорит о сложности проблемы копирования. Проблемы у программистов на <b>C#</b> — такие же. | |
- | + | ||
- | В общем случае всё это говорит о сложности проблемы копирования. Проблемы у программистов на | + | |
== Модульность и раздельная трансляция == | == Модульность и раздельная трансляция == | ||
Строка 1242: | Строка 1170: | ||
== Исключительные ситуации и обработка ошибок == | == Исключительные ситуации и обработка ошибок == | ||
- | + | Исключения есть в Си++, Ада 83, Ада 95, Visual Basic, C#, Java, Delphi | |
- | + | ||
=== Исключения и блоки try {} catch {} finally {}. Семантика возобновления и семантика завершения. === | === Исключения и блоки try {} catch {} finally {}. Семантика возобновления и семантика завершения. === | ||
Строка 1349: | Строка 1276: | ||
Do_Smth; | Do_Smth; | ||
'''end'''; | '''end'''; | ||
+ | |||
+ | '''finally-блока в Аде таки нету.''' Однако он [http://stackoverflow.com/questions/4804135/best-practice-for-implementing-in-ada-2005-or-2012-an-equivalent-of-the-java-f имитируется]. | ||
Отлов исключения так же может иметь такой вид: | Отлов исключения так же может иметь такой вид: | ||
Строка 1401: | Строка 1330: | ||
=== C# === | === C# === | ||
- | В | + | В <b>C#</b> к динамическому полиморфизму имеют отношение 3 важных ключевых слова (модификатора): |
- | : 1. | + | : 1. <b>virtual</b> |
- | : 2. | + | : 2. <b>override</b> |
- | : 3. | + | : 3. <b>new</b> |
==== virtual ==== | ==== virtual ==== | ||
- | Ключевое слово | + | Ключевое слово <b>virtual</b> используется для изменения объявлений методов, свойств, индексаторов и событий и разрешения их переопределения в производном классе. Например, этот метод может быть переопределен любым производным классом. Модификатор <b>virtual</b> нельзя использовать с модификаторами <b>static, abstract, private</b> или <b>override.</b> |
public virtual double Area() | public virtual double Area() | ||
Строка 1415: | Строка 1344: | ||
==== override ==== | ==== override ==== | ||
- | Модификатор | + | Модификатор <b>override</b> требуется для расширения или изменения абстрактной или виртуальной реализации унаследованного метода, свойства, индексатора или события. Иными словами, модификатор <b>override</b> <i>расширяет</i> метод базового класса. Метод, переопределенный c использованием <b>override,</b> называется переопределенным базовым методом. Переопределенный базовый метод должен иметь ту же сигнатуру, что и метод <b>override.</b> Невиртуальный или статический метод нельзя переопределить. Переопределенный базовый метод должен иметь тип <b>virtual, abstract</b> или <b>override.</b> Объявление <b>override</b> не может изменить уровень доступа метода <b>virtual.</b> Методы <b>override</b> и <b>virtual</b> должны иметь одинаковый модификатор уровня доступа. |
- | Модификаторы | + | Модификаторы <b>new, static</b> и <b>virtual</b> нельзя использовать для изменения метода <b>override.</b> |
- | Переопределяющее объявление свойства должно задавать такие же модификаторы уровня доступа, тип и имя, как и имеющиеся у унаследованного свойства, а переопределенное свойство должно иметь тип | + | Переопределяющее объявление свойства должно задавать такие же модификаторы уровня доступа, тип и имя, как и имеющиеся у унаследованного свойства, а переопределенное свойство должно иметь тип <b>virtual, abstract</b> или <b>override.</b> |
class BaseClass | class BaseClass | ||
Строка 1460: | Строка 1389: | ||
==== new ==== | ==== new ==== | ||
- | Модификатор | + | Модификатор <b>new</b> <i>скрывает</i> члены, унаследованные от базового класса. При сокрытии унаследованного члена его производная версия заменяет версию базового класса. (На самом деле, члены можно скрыть и без модификатора <b>new,</b> но в результате возникнет предупреждение. Если же для явного скрытия члена используется <b>new,</b> то модификатор отключает вывод предупреждений и документирует тот факт, что производная версия предназначена для замены. |
class BaseClass | class BaseClass | ||
Строка 1520: | Строка 1449: | ||
abstract int Length { get;} | abstract int Length { get;} | ||
- | Пример абстрактного класса ( | + | Пример абстрактного класса (<b>Java</b> или <b>C#</b>): |
abstract class ShapesClass | abstract class ShapesClass | ||
{ | { | ||
Строка 1532: | Строка 1461: | ||
В большинстве языков абстрактный тип данных реализуется с помощью интерфейсов. См. пример в соответствующем разделе. | В большинстве языков абстрактный тип данных реализуется с помощью интерфейсов. См. пример в соответствующем разделе. | ||
- | В Ада используется ключевое слово | + | В Ада используется ключевое слово <b>limited:</b> |
type Stack is limited private; | type Stack is limited private; | ||
В ОБЕРОН И ОБЕРОН-2 АТД позволяют открывать поля структуры. | В ОБЕРОН И ОБЕРОН-2 АТД позволяют открывать поля структуры. | ||
Строка 1599: | Строка 1528: | ||
class CoClass: ISomeInterface | class CoClass: ISomeInterface | ||
{ | { | ||
- | + | ISomeInterface.F() { //в случае неявного интерфейса, здесь стояло бы F() { | |
System.Console.WriteLine(“Явно реализованный метод”); | System.Console.WriteLine(“Явно реализованный метод”); | ||
} | } | ||
Строка 1610: | Строка 1539: | ||
// интерфейса через ссылку на объект | // интерфейса через ссылку на объект | ||
- | + | (ISomeInterface)c.F(); // все нормально | |
== Множественное наследование == | == Множественное наследование == | ||
Строка 1672: | Строка 1601: | ||
== Понятие о родовых объектах. Обобщенное программирование == | == Понятие о родовых объектах. Обобщенное программирование == | ||
=== ADA === | === ADA === | ||
- | Note to C++ programmers: generic units are similar to C++ templates. | + | Note to C++ programmers: generic units are similar to C++ templates. [http://www.example.com Ada Programming] |
Объявляем шаблон: | Объявляем шаблон: | ||
Строка 1765: | Строка 1694: | ||
== Параллельное программирование == | == Параллельное программирование == | ||
- | |||
=== ADA === | === ADA === | ||
Ада реализует концепцию так называемых задач ('''task'''), что по сути является синонимом потока. Задача оформляется совершенно аналогично модулю, но может быть объявлена и описана где угодно, даже в теле подпрограммы: | Ада реализует концепцию так называемых задач ('''task'''), что по сути является синонимом потока. Задача оформляется совершенно аналогично модулю, но может быть объявлена и описана где угодно, даже в теле подпрограммы: | ||
Строка 1837: | Строка 1765: | ||
В этом примере, естественно лучше было все 3 '''accept''' запихнуть в '''select''' - было бы меньше простоев, но для примера я оставил так. | В этом примере, естественно лучше было все 3 '''accept''' запихнуть в '''select''' - было бы меньше простоев, но для примера я оставил так. | ||
- | |||
- | === Modula-2 === | ||
- | |||
- | В языке Modula-2 есть низкоуровневый механизм ''сопрограмм''. | ||
- | |||
- | Отличия сопрограммы от процесса: | ||
- | # Известно, что сопрограммы выполняются квазипараллельно. Следовательно, их использование исключает трудную проблему взаимодействия истинно параллельных процессов. | ||
- | # Переключение процессора от одной сопрограммы к другой осществляется явным ''оператором передачи управления''. Выполнение сопрограммы, которой передаётся управление, возобновляется с той точки, где она была приостановлена последним таким оператором. | ||
== Примеры кода == | == Примеры кода == | ||
Строка 2303: | Строка 2223: | ||
=== Примеры кода на С# === | === Примеры кода на С# === | ||
- | Пример обработки исключений в | + | Пример обработки исключений в <b>C#.</b> |
class NegativeValueException : Exception | class NegativeValueException : Exception | ||
Строка 2351: | Строка 2271: | ||
} | } | ||
- | + | Event в C# (грубо говоря, это эмуляция асинхронности): | |
using System; | using System; | ||
Строка 2358: | Строка 2278: | ||
public class Metronome | public class Metronome | ||
{ | { | ||
- | public event TickHandler Tick; // | + | public event TickHandler Tick; // ! |
public EventArgs e = null; | public EventArgs e = null; | ||
public delegate void TickHandler(Metronome m, EventArgs e); | public delegate void TickHandler(Metronome m, EventArgs e); | ||
Строка 2368: | Строка 2288: | ||
if (Tick != null) | if (Tick != null) | ||
{ | { | ||
- | Tick(this, e); | + | Tick(this, e); |
} | } | ||
} | } | ||
Строка 2377: | Строка 2297: | ||
public void Subscribe(Metronome m) | public void Subscribe(Metronome m) | ||
{ | { | ||
- | // регистрируем обработчик события Tick | ||
m.Tick += new Metronome.TickHandler(HeardIt); | m.Tick += new Metronome.TickHandler(HeardIt); | ||
} | } | ||
Строка 2398: | Строка 2317: | ||
} | } | ||
- | + | Если удалить ключевое слово event, то слушающий класс не будет оповещен о событии (предположительно, могу ошибаться). | |
- | + | ||
=== Моделирование приватных типов данных из Ады в C++ === | === Моделирование приватных типов данных из Ады в C++ === | ||
Строка 2503: | Строка 2421: | ||
|есть | |есть | ||
|- | |- | ||
- | !Виртуальные методы | + | !Виртуальные методы |
- | |нет | + | |нет |
|есть | |есть | ||
|есть | |есть | ||
Строка 2512: | Строка 2430: | ||
|нет | |нет | ||
|есть | |есть | ||
- | | | + | |есть<ref>Причём, каждый метод виртуален; взято [http://computer-programming-forum.com/27-modula2/2a715a4b1cce6ba6.htm отсюда].</ref> |
|нет | |нет | ||
|есть | |есть | ||
Строка 2554: | Строка 2472: | ||
|нет | |нет | ||
|нет | |нет | ||
+ | |- | ||
+ | !Понятие связывания подпрограмм (методов класса) на этапе выполнения (динамическое связывание) | ||
+ | |нет<ref>Обычно реализуется через указатели на функции и указатели на структуры с указателями на функции.</ref> | ||
+ | |есть | ||
+ | |есть | ||
+ | |есть | ||
+ | |нет | ||
+ | |есть | ||
+ | |нет | ||
+ | |есть | ||
+ | |нет | ||
+ | |нет | ||
+ | |есть | ||
|- | |- | ||
!Раздельная независимая трансляция | !Раздельная независимая трансляция | ||
Строка 2610: | Строка 2541: | ||
|нет | |нет | ||
|нет | |нет | ||
- | |есть<ref>Используется ключевое слово | + | |есть<ref>Используется ключевое слово <b>sealed</b>.</ref> |
- | |есть<ref>Используется ключевое слово | + | |есть<ref>Используется ключевое слово <b>final</b>.</ref> |
|нет | |нет | ||
|нет | |нет | ||
Строка 2648: | Строка 2579: | ||
!Вложенные модули | !Вложенные модули | ||
|нет | |нет | ||
- | |есть<ref>См. статью [ | + | |есть<ref>См. статью [www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2073.pdf «Модули в С++»].</ref> |
|есть | |есть | ||
|нет (?) | |нет (?) | ||
Строка 2768: | Строка 2699: | ||
|есть | |есть | ||
|есть<ref>cм. [http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx#vclrfpassingmethodparameters_valuetypes MSDN].</ref> | |есть<ref>cм. [http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx#vclrfpassingmethodparameters_valuetypes MSDN].</ref> | ||
- | |есть | + | |есть<ref>Только для простых типов (см. примечание для ячейки ниже).</ref> |
|есть | |есть | ||
|есть | |есть | ||
Строка 2779: | Строка 2710: | ||
!Передача параметров по ссылке | !Передача параметров по ссылке | ||
|и<ref>Моделируется с помощью указателей.</ref> | |и<ref>Моделируется с помощью указателей.</ref> | ||
- | |и | + | |и<ref>Специальной конструкции для передачи значения по ссылке нет. Однако, есть ссылочный тип. Переменная ссылочного типа может ссылаться на значение любого типа, должна быть инициализирована и не может менять значения. С помощью передачи переменной ссылочного типа можно имитировать все возможности контрукции var из '''Pascal'''. Но можно действовать в стиле C — передавать указатель (при этом его даже можно поменять, передав в функцию/метод «по указателю» или «по ссылке»).</ref> |
|есть<ref>Модификаторы '''ref''' и '''out''', также см. [http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx#vclrfpassingmethodparameters_referencetypes MSDN].</ref> | |есть<ref>Модификаторы '''ref''' и '''out''', также см. [http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx#vclrfpassingmethodparameters_referencetypes MSDN].</ref> | ||
- | |и | + | |и<ref>Специальной конструкции для передачи значения по ссылке нет. Однако, есть ссылочный тип. Переменная ссылочного типа может ссылаться только на объекты (экземпляры классов и массивы), может иметь специальное значение null и изменяема. Простые типы можно передавать «по ссылке» с помощью соответствующих классов-обёрток.</ref> |
|есть<ref name="keyword_var">Ключевое слово var.</ref> | |есть<ref name="keyword_var">Ключевое слово var.</ref> | ||
|есть<ref name="keyword_var" /> | |есть<ref name="keyword_var" /> |