Редактирование: Сравнение Языков Программирования
Материал из eSyr's wiki.
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
ПРЕДУПРЕЖДЕНИЕ: Длина этой страницы составляет 148 килобайт. Страницы, размер которых приближается к 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; | ||
Строка 71: | Строка 75: | ||
Есть еще очень много интересного по этой теме. Все было взято [http://en.wikibooks.org/wiki/Ada_Programming/Types/access тут]. | Есть еще очень много интересного по этой теме. Все было взято [http://en.wikibooks.org/wiki/Ada_Programming/Types/access тут]. | ||
- | === ОБЕРОН и ОБЕРОН-2 === | + | === ОБЕРОН и ОБЕРОН-2: === |
; Отличия: | ; Отличия: | ||
Строка 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> <тип> <имя_переменной> = <значение>; | |
// Значение переменной не может изменяться после инициализации (инициализация обязательна). | // Значение переменной не может изменяться после инициализации (инициализация обязательна). | ||
Строка 229: | Строка 230: | ||
== Массивы == | == Массивы == | ||
- | === Длина массива | + | === Длина массива - статический или динамический атрибут. === |
- | + | <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>C#</b> и <b>Java</b> неявными могут быть только расширяющие преобразования; в <b>С++</b> — любые преобразования. | ||
- | + | === Понятия <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: | Строка 346: | ||
==== Java ==== | ==== Java ==== | ||
- | В | + | В <b>Java</b> автоупаковка и автораспаковка поддерживаются начиная с J2SE 5.0 (сентябрь 2004 года). |
Пример упаковки и распаковки: | Пример упаковки и распаковки: | ||
Строка 423: | Строка 357: | ||
==== Другие языки ==== | ==== Другие языки ==== | ||
- | В некоторых языках упаковка и распаковка отсутствуют. Например, в | + | В некоторых языках упаковка и распаковка отсутствуют. Например, в <b>Smalltalk</b> любое значение принадлежит некоторому классу (т.е. даже значения простых типов являются экземплярами классов). Немного по другой причине этих операций нет и в <b>JavaScript</b>: в этом языке отсутствует понятие "класс", т.к. он является прототипным. |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
== Операторный базис языков программирования. Управление последовательностью вычислений == | == Операторный базис языков программирования. Управление последовательностью вычислений == | ||
=== ADA === | === ADA === | ||
- | + | Джентльменский набор: | |
+ | |||
'''if''' condition '''then''' | '''if''' condition '''then''' | ||
statement; | statement; | ||
Строка 712: | Строка 638: | ||
== Процедурные абстракции == | == Процедурные абстракции == | ||
- | === Передача параметров в | + | === Передача параметров в подпрограммах === |
- | + | Для каждой подпрограммы указывается набор формальных параметров. Можно рассматривать формальные параметры как локальные | |
- | Для каждой подпрограммы указывается набор формальных параметров. Можно рассматривать формальные параметры как локальные переменные тела подпрограммы. При вызове подпрограммы указывается список фактических параметров. Соответствие между фактическими и формальными параметрами выполняется по позиции в списке: первый фактический параметр соответствует первому формальному параметру и т. д. Такой способ называется | + | переменные тела подпрограммы. При вызове подпрограммы указывается список фактических параметров. Соответствие между фактическими и формальными параметрами |
- | + | выполняется по позиции в списке: первый фактический параметр соответствует первому формальному параметру и т.д. Такой | |
- | + | способ называется <i>позиционным.</i> Язык С#, начиная с версии 4, предусматривает альтернативный — <i>ключевой</i> способ отождествления, в котором используются имена формальных параметров, но мы не будем его рассматривать.Существует три вида формальных параметров: | |
- | + | : • входные параметры (параметры, от которых требуется только значение). Мы используем только значения фактических параметров, которые не меняются при : : выходе из тела функции; | |
- | + | : • выходные параметры (эти параметры не обязаны иметь начальное значение, но могут быть изменены в теле функции); | |
- | С входным параметром может связываться произвольное выражение, а выходным или изменяемым — только объекты, которые могут стоять в левой части оператора присваивания. В большинстве языков программирования вместо указания вида параметра указывается способ (механизм) связывания параметра, называемый способом передачи параметра. | + | : • изменяемые параметры (требуется и исходное значение, и возможность его изменения). |
- | + | С входным параметром может связываться произвольное выражение, а выходным или изменяемым — только объекты, которые могут стоять в левой части оператора присваивания. В большинстве языков программирования вместо указания вида параметра указывается способ (механизм) связывания параметра, | |
- | Существует два основных способа передачи параметров: | + | называемый способом передачи параметра. |
- | + | Существует два основных способа передачи параметров: <i>по значению</i> и <i>по ссылке.</i> | |
- | ==== Передача параметров по значению ==== | + | ==== Передача параметров по значению. ==== |
- | + | Формальный параметр есть некоторая локальная переменная. Место для локальных переменных отводится в стеке. При вызове подпрограммы значение | |
- | Формальный параметр есть некоторая локальная переменная. Место для локальных переменных отводится в стеке. При вызове подпрограммы значение фактического параметра копируется в соответствующий формальный параметр. Все изменения формального параметра связаны с изменением локальной переменной и не сказываются на фактическом параметре. Перед копированием может потребоваться приведение типа, если типы фактического и формального параметров не совпадают. | + | фактического параметра копируется в соответствующий формальный параметр. Все изменения формального параметра связаны с изменением локальной переменной и не сказываются на фактическом параметре. Перед копированием может потребоваться приведение типа, если типы фактического и формального |
- | + | параметров не совпадают. | |
- | ==== Передача параметров по ссылке ==== | + | ==== Передача параметров по ссылке. ==== |
- | + | Фактически этот способ есть передача ссылки по значению. Формальный параметр — это ссылка на объект. В момент вызова происходит инициализация ссылки | |
- | Фактически этот способ есть передача ссылки по значению. Формальный параметр — это ссылка на объект. | + | фактическим параметром. Преобразования типов в этот момент не происходит: типы формального и фактического параметров должны совпадать. Поскольку ссылка после инициализации отождествляется с объектом, то любые изменения формального параметра подразумевают изменения фактического параметра. |
- | + | Очевидно, что способ передачи по значению соответствует семантике | |
- | + | входных формальных параметров. | |
- | + | По ссылке можно передавать выходные и изменяемые параметры. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
=== Перегрузка операций === | === Перегрузка операций === | ||
Ада 83, Ада 95, Си++, Java, Delphi, C# | Ада 83, Ада 95, Си++, Java, Delphi, C# | ||
Строка 861: | Строка 773: | ||
При подключении потомка родитель-пакет подключается автоматически. | При подключении потомка родитель-пакет подключается автоматически. | ||
- | + | О подключениях. Подключить пакет можно с помощью конструкции '''with'''. | |
'''with''' Points.RandomDistributions; | '''with''' Points.RandomDistributions; | ||
После этого можно будет пользоваться ввсем, что в пакете лежит, через точечную нотацию. Если же вызовов слишком много, то можно влить содержимое пакета в текущую область видимости с помощью '''use''' (только после подключения!). | После этого можно будет пользоваться ввсем, что в пакете лежит, через точечную нотацию. Если же вызовов слишком много, то можно влить содержимое пакета в текущую область видимости с помощью '''use''' (только после подключения!). | ||
Строка 927: | Строка 839: | ||
Обычно выделяют следующие типы конструкторов: конструктор по умолчанию, конструктор копирования и конструктор преобразования. Конструкторы имеют пользовательскую (тело объявленного конструктора) и системную (сгенерированный код) части. | Обычно выделяют следующие типы конструкторов: конструктор по умолчанию, конструктор копирования и конструктор преобразования. Конструкторы имеют пользовательскую (тело объявленного конструктора) и системную (сгенерированный код) части. | ||
- | ==== Деструкторы и финализаторы ==== | + | ==== Деструкторы и финализаторы==== |
- | Деструкторы и финализаторы — это специальные функции-члены класса, автоматически вызываемые при уничтожении объекта класса. Роль деструкторов и финализаторов — освобождение захваченных объектом ресурсов. Если объект не захватывает ресурсы или ресурсы освобождаются автоматически, то нужды в деструкторе (финализаторе) нет. Деструкторы | + | Деструкторы и финализаторы — это специальные функции-члены класса, автоматически вызываемые при уничтожении объекта класса. Роль деструкторов и финализаторов — освобождение захваченных объектом ресурсов. Если объект не захватывает ресурсы или ресурсы освобождаются автоматически, то нужды в деструкторе (финализаторе) нет. Деструкторы <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: | Строка 910: | ||
FMyField := Value; | FMyField := Value; | ||
end; | end; | ||
- | |||
==== Статические классы ==== | ==== Статические классы ==== | ||
- | + | Под <i>статическим классом</i> понимается разновидность класса, все члены которого объявлены статическими. Как правило, у таких классов не описаны конструктор и деструктор. Использовать статические члены класса можно не создавая самого экземпляра класса. Понятие статического класса чаще всего используется в языках <b>C#</b> и <b>Java.</b> В этих языках невозможно создать экземпляр статического класса; также статический класс не может реализовывать интерфейсы. В <b>C#</b> любой статический класс наследуется от типа object. В <b>С++</b> понятие статического класса как таковое отсутствует. Имитировать статический класс можно либо создав класс, все члены которого объявлены статическими, и запретив создание его экземпляров с помощью модификатора доступа private перед конструктором; либо используя шаблон проектирования singleton - в таком случае, будет существовать <i>ровно один</i> экземпляр данного класса, и будет предоставлена глобальная точка доступа к данному экземпляру. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
=== Объединение типов (запись с вариантами) === | === Объединение типов (запись с вариантами) === | ||
Строка 1068: | Строка 918: | ||
Размеченное объединение типов содержит одно выделенное поле (дискретного типа данных) — общее для всех вариантов. Такое поле называется дискриминантом. Значение дискриминанта определяет, по какому варианту выделена память в переменной-экземпляре размеченного объединения. | Размеченное объединение типов содержит одно выделенное поле (дискретного типа данных) — общее для всех вариантов. Такое поле называется дискриминантом. Значение дискриминанта определяет, по какому варианту выделена память в переменной-экземпляре размеченного объединения. | ||
+ | |||
+ | Есть в Pascal, Модула, Ада. | ||
=== Семантика копирования === | === Семантика копирования === | ||
Проблема копирования состоит в том, что копируемый объект может содержать ссылки на другие объекты. Проблема копирования состоит в том, что объекты могут содержать ссылки на другие объекты. При копировании таких ссылок возникает дилемма: копировать либо только ссылку, либо полностью | Проблема копирования состоит в том, что копируемый объект может содержать ссылки на другие объекты. Проблема копирования состоит в том, что объекты могут содержать ссылки на другие объекты. При копировании таких ссылок возникает дилемма: копировать либо только ссылку, либо полностью | ||
- | содержимое объекта, на который указывает ссылка. Первый вид копирования называется | + | содержимое объекта, на который указывает ссылка. Первый вид копирования называется <i>поверхностным</i>, а второй — <i>глубоким.</i> В общем случае транслятор не в состоянии выбрать нужную семантику копирования, поэтому в языках программирования, которые мы рассматриваем, принята следующая схема: по умолчанию реализуется <i>поверхностное копирование,</i> но программисту предоставляются средства для указания <i>глубокой семантики копирования.</i> В <b>C++</b> этими средствами являются переопределение конструктора копирования и операции присваивания, в <b>Java</b> и <b>C#</b> — наследование и реализация специального интерфейса. |
==== Особенности копирования объектов в Java ==== | ==== Особенности копирования объектов в Java ==== | ||
Строка 1089: | Строка 941: | ||
* 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: | Строка 1092: | ||
== Исключительные ситуации и обработка ошибок == | == Исключительные ситуации и обработка ошибок == | ||
- | + | Исключения есть в Си++, Ада 83, Ада 95, Visual Basic, C#, Java, Delphi | |
- | + | ||
=== Исключения и блоки try {} catch {} finally {}. Семантика возобновления и семантика завершения. === | === Исключения и блоки try {} catch {} finally {}. Семантика возобновления и семантика завершения. === | ||
Строка 1349: | Строка 1198: | ||
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: | Строка 1252: | ||
=== 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: | Строка 1266: | ||
==== 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: | Строка 1311: | ||
==== new ==== | ==== new ==== | ||
- | Модификатор | + | Модификатор <b>new</b> <i>скрывает</i> члены, унаследованные от базового класса. При сокрытии унаследованного члена его производная версия заменяет версию базового класса. (На самом деле, члены можно скрыть и без модификатора <b>new,</b> но в результате возникнет предупреждение. Если же для явного скрытия члена используется <b>new,</b> то модификатор отключает вывод предупреждений и документирует тот факт, что производная версия предназначена для замены. |
class BaseClass | class BaseClass | ||
Строка 1520: | Строка 1371: | ||
abstract int Length { get;} | abstract int Length { get;} | ||
- | Пример абстрактного класса ( | + | Пример абстрактного класса (<b>Java</b> или <b>C#</b>): |
abstract class ShapesClass | abstract class ShapesClass | ||
{ | { | ||
Строка 1532: | Строка 1383: | ||
В большинстве языков абстрактный тип данных реализуется с помощью интерфейсов. См. пример в соответствующем разделе. | В большинстве языков абстрактный тип данных реализуется с помощью интерфейсов. См. пример в соответствующем разделе. | ||
- | В Ада используется ключевое слово | + | В Ада используется ключевое слово <b>limited:</b> |
type Stack is limited private; | type Stack is limited private; | ||
В ОБЕРОН И ОБЕРОН-2 АТД позволяют открывать поля структуры. | В ОБЕРОН И ОБЕРОН-2 АТД позволяют открывать поля структуры. | ||
Строка 1599: | Строка 1450: | ||
class CoClass: ISomeInterface | class CoClass: ISomeInterface | ||
{ | { | ||
- | + | ISomeInterface.F() { //в случае неявного интерфейса, здесь стояло бы F() { | |
System.Console.WriteLine(“Явно реализованный метод”); | System.Console.WriteLine(“Явно реализованный метод”); | ||
} | } | ||
Строка 1610: | Строка 1461: | ||
// интерфейса через ссылку на объект | // интерфейса через ссылку на объект | ||
- | + | (ISomeInterface)c.F(); // все нормально | |
== Множественное наследование == | == Множественное наследование == | ||
Строка 1672: | Строка 1523: | ||
== Понятие о родовых объектах. Обобщенное программирование == | == Понятие о родовых объектах. Обобщенное программирование == | ||
=== 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: | Строка 1616: | ||
== Параллельное программирование == | == Параллельное программирование == | ||
- | |||
=== ADA === | === ADA === | ||
Ада реализует концепцию так называемых задач ('''task'''), что по сути является синонимом потока. Задача оформляется совершенно аналогично модулю, но может быть объявлена и описана где угодно, даже в теле подпрограммы: | Ада реализует концепцию так называемых задач ('''task'''), что по сути является синонимом потока. Задача оформляется совершенно аналогично модулю, но может быть объявлена и описана где угодно, даже в теле подпрограммы: | ||
Строка 1837: | Строка 1687: | ||
В этом примере, естественно лучше было все 3 '''accept''' запихнуть в '''select''' - было бы меньше простоев, но для примера я оставил так. | В этом примере, естественно лучше было все 3 '''accept''' запихнуть в '''select''' - было бы меньше простоев, но для примера я оставил так. | ||
- | |||
- | === Modula-2 === | ||
- | |||
- | В языке Modula-2 есть низкоуровневый механизм ''сопрограмм''. | ||
- | |||
- | Отличия сопрограммы от процесса: | ||
- | # Известно, что сопрограммы выполняются квазипараллельно. Следовательно, их использование исключает трудную проблему взаимодействия истинно параллельных процессов. | ||
- | # Переключение процессора от одной сопрограммы к другой осществляется явным ''оператором передачи управления''. Выполнение сопрограммы, которой передаётся управление, возобновляется с той точки, где она была приостановлена последним таким оператором. | ||
== Примеры кода == | == Примеры кода == | ||
Строка 2302: | Строка 2144: | ||
function G_MatMult(A,B: Matrix) return Matrix; | function G_MatMult(A,B: Matrix) return Matrix; | ||
- | === | + | === Пример кода на С# === |
- | Пример обработки исключений в | + | Пример обработки исключений в <b>C#.</b> |
class NegativeValueException : Exception | class NegativeValueException : Exception | ||
Строка 2350: | Строка 2192: | ||
} | } | ||
} | } | ||
- | |||
- | Ключевое слово ''event'' в '''C#''' позволяет уменьшить объём кода, необходимого для реализации событийной модели взаимодействия на делегатах. Иначе говоря, это такой синтаксический сахар для упрощения работы с обратными вызовами. | ||
- | |||
- | using System; | ||
- | namespace wildert | ||
- | { | ||
- | public class Metronome | ||
- | { | ||
- | public event TickHandler Tick; // объявляем событие Tick | ||
- | public EventArgs e = null; | ||
- | public delegate void TickHandler(Metronome m, EventArgs e); | ||
- | public void Start() | ||
- | { | ||
- | while (true) | ||
- | { | ||
- | System.Threading.Thread.Sleep(3000); | ||
- | if (Tick != null) | ||
- | { | ||
- | Tick(this, e); // генерируем событие Tick | ||
- | } | ||
- | } | ||
- | } | ||
- | } | ||
- | public class Listener | ||
- | { | ||
- | public void Subscribe(Metronome m) | ||
- | { | ||
- | // регистрируем обработчик события Tick | ||
- | m.Tick += new Metronome.TickHandler(HeardIt); | ||
- | } | ||
- | private void HeardIt(Metronome m, EventArgs e) | ||
- | { | ||
- | System.Console.WriteLine("HEARD IT"); | ||
- | } | ||
- | |||
- | } | ||
- | class Test | ||
- | { | ||
- | static void Main() | ||
- | { | ||
- | Metronome m = new Metronome(); | ||
- | Listener l = new Listener(); | ||
- | l.Subscribe(m); | ||
- | m.Start(); | ||
- | } | ||
- | } | ||
- | } | ||
- | |||
- | ; Замечание | ||
- | : Делегат — это тип, который определяет сигнатуру метода. При создании экземпляра делегата можно связать этот экземпляр с любым методом с совместимой сигнатурой. Метод можно запустить (или вызвать) с помощью экземпляра делегата. Делегаты похожи на указатели на функции в C++.<ref>Процитировано из [http://msdn.microsoft.com/ru-ru/library/ms173171.aspx msdn].</ref> | ||
=== Моделирование приватных типов данных из Ады в C++ === | === Моделирование приватных типов данных из Ады в C++ === | ||
Строка 2503: | Строка 2295: | ||
|есть | |есть | ||
|- | |- | ||
- | !Виртуальные методы | + | !Виртуальные методы |
- | |нет | + | |нет |
|есть | |есть | ||
|есть | |есть | ||
Строка 2512: | Строка 2304: | ||
|нет | |нет | ||
|есть | |есть | ||
- | | | + | |есть<ref>Причём, каждый метод виртуален; взято [http://computer-programming-forum.com/27-modula2/2a715a4b1cce6ba6.htm отсюда].</ref> |
|нет | |нет | ||
|есть | |есть | ||
Строка 2554: | Строка 2346: | ||
|нет | |нет | ||
|нет | |нет | ||
+ | |- | ||
+ | !Понятие связывания подпрограмм (методов класса) на этапе выполнения (динамическое связывание) | ||
+ | |нет<ref>Обычно реализуется через указатели на функции и указатели на структуры с указателями на функции.</ref> | ||
+ | |есть | ||
+ | |есть | ||
+ | |есть | ||
+ | |нет | ||
+ | |есть | ||
+ | |нет | ||
+ | |есть | ||
+ | |нет | ||
+ | |нет | ||
+ | |есть | ||
|- | |- | ||
!Раздельная независимая трансляция | !Раздельная независимая трансляция | ||
Строка 2591: | Строка 2396: | ||
|нет<ref>Нет в Оберон; учитывая характер изменений, внесённых в Оберон-2, делаем вывод о том, что размеченных объединений в нём нет. </ref> | |нет<ref>Нет в Оберон; учитывая характер изменений, внесённых в Оберон-2, делаем вывод о том, что размеченных объединений в нём нет. </ref> | ||
|есть | |есть | ||
- | |есть<ref | + | |есть<ref>Есть в Ада; вероятно, есть и в конкретной реализации.</ref> |
- | |есть<ref | + | |есть<ref>См. предыдущее примечание.</ref> |
|- | |- | ||
!Перечисления | !Перечисления | ||
Строка 2606: | Строка 2411: | ||
|есть | |есть | ||
|есть | |есть | ||
+ | |- | ||
+ | !Оператор loop | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | |есть | ||
+ | |есть | ||
+ | |есть | ||
+ | |есть | ||
+ | |есть | ||
+ | |- | ||
+ | !Оператор with | ||
+ | |нет | ||
+ | |нет | ||
+ | |нет | ||
+ | |нет | ||
+ | |есть | ||
+ | |есть | ||
+ | |нет | ||
+ | |есть | ||
+ | |есть | ||
+ | |нет<ref>Ключевое слово '''with''' означает импортирование классов в текущую область видимости.</ref> | ||
+ | |нет | ||
|- | |- | ||
!Запрещение замещения метода в произвольных классах или наследования класса | !Запрещение замещения метода в произвольных классах или наследования класса | ||
|нет | |нет | ||
|нет | |нет | ||
- | |есть<ref>Используется ключевое слово | + | |есть<ref>Используется ключевое слово <b>sealed</b>.</ref> |
- | |есть<ref>Используется ключевое слово | + | |есть<ref>Используется ключевое слово <b>final</b>.</ref> |
|нет | |нет | ||
|нет | |нет | ||
Строка 2647: | Строка 2478: | ||
|- | |- | ||
!Вложенные модули | !Вложенные модули | ||
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | |нет<ref | + | | |
- | |нет<ref | + | |нет<ref>Вложенными могут быть только подпрограммы, которые не являются библиотечными модулями.</ref> |
- | |нет<ref | + | |нет<ref>См. предыдущее примечание.</ref> |
- | + | |нет<ref>См. предыдущее примечание.</ref> | |
|есть | |есть | ||
|есть | |есть | ||
Строка 2670: | Строка 2501: | ||
|есть | |есть | ||
|ч/и<ref>Делаем структуру, скрыто экспортируем указатель на неё в другой модуль.</ref> | |ч/и<ref>Делаем структуру, скрыто экспортируем указатель на неё в другой модуль.</ref> | ||
- | | | + | | |
- | | | + | | |
|- | |- | ||
!Расширяющее программирование | !Расширяющее программирование | ||
Строка 2704: | Строка 2535: | ||
|и | |и | ||
|и | |и | ||
- | |нет<ref>Стандарт Паскаля — не поддерживает! [ | + | |нет<ref>Стандарт Паскаля — не поддерживает! [http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D0%9F%D0%B0%D1%81%D0%BA%D0%B0%D0%BB%D1%8C Компонентный Паскаль] и далее — поддерживают.</ref> |
|и | |и | ||
|и | |и | ||
Строка 2760: | Строка 2591: | ||
|и | |и | ||
|и | |и | ||
- | | | + | | |
- | | | + | | |
- | | | + | | |
|- | |- | ||
!Передача параметров по значению | !Передача параметров по значению | ||
Строка 2768: | Строка 2599: | ||
|есть | |есть | ||
|есть<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> | ||
|есть | |есть | ||
|есть | |есть | ||
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | + | ||
|- | |- | ||
!Передача параметров по ссылке | !Передача параметров по ссылке | ||
|и<ref>Моделируется с помощью указателей.</ref> | |и<ref>Моделируется с помощью указателей.</ref> | ||
- | | | + | |есть<ref>Но можно действовать в стиле 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>Только для ссылочных типов (точнее, значений, на которые они ссылаются). По ссылке передаётся объект, ссылочная переменная передаётся по значению.</ref> | |
- | |есть<ref | + | |есть |
- | |есть | + | |есть |
- | |есть | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
|} | |} | ||
:ч/и - частично имитируется | :ч/и - частично имитируется |