В Delphi методы должны объявляться внутри класса, а описываться - вне класса, при этом перед именем метода пишется имя класса с последующей точкой:
type Person = class private nm: string; // имя ag: integer; // возраст procedure SetAge(ag: integer); public constructor Create(nm: string; ag: integer); property Name: string read nm; property Age: integer read ag write SetAge; end; constructor Person.Create(nm: string; ag: integer); begin Self.nm := nm; Self.ag := ag; end; procedure Person.SetAge(ag: integer); begin if ag<0 then ag := 0; Self.ag := ag; end;
Удобен ли такой метод? Несомненно: при взгляде на класс сразу виден его интерфейс. А реализация дана ниже. Если класс находится в модуле, то его интерфейс помещается в интерфейсную секцию модуля, а реализация методов - в секцию реализации модуля.
Немного раздражают лишние детали: например, для использования класса достаточно знать его открытый интерфейс и вовсе не нужно знать, какие методы используются для чтения и записи свойств. То есть в идеале для пользователя класс должен предстать в следующем обличье:
type Person = class public constructor Create(nm: string; ag: integer); property Name: string read; property Age: integer read write; end;
В Java и C# принято прямо противоположное решение: все методы определяются только внутри интерфейса класса. Например, тот же класс на C# будет описываться так:
При таком способе все описывается сразу, что очень удобно, но есть две проблемы. Во-первых, интерфейс класса становится труднообозримым. Во-вторых, трудно перемещаться по большому классу в 200-300-1000 строк в поисках нужного метода. Обе проблемы решаются специальными средствами оболочки, позволяющимися вычленять из класса его интерфейс и перемещаться к нужному методу.
В C++ принято демократичное решение: методы могут описываться как внутри, так и вне класса. Это очень удобно: мелкие методы реализуются на месте, более крупные выносятся вовне чтобы не захламлять интерфейс класса.
В PascalABC.NET принято такое же демократическое решение: методы можно определять как внутри, так и вне интерфейса класса. Например, код нашего класса можно записать следующим образом:
type Person = class private nm: string; // имя ag: integer; // возраст procedure SetAge(ag: integer); begin if ag<0 then ag := 0; Self.ag := ag; end; public constructor Create(nm: string; ag: integer); begin Self.nm := nm; Self.ag := ag; end; property Name: string read nm; property Age: integer read ag write SetAge; end;
Конечно, наследуются недостатки обоих способов. Но есть и преимущества. Они просты.
1. При начальном обучении классам достаточно сказать, что класс - это всего лишь оболочка над переменными и подпрограммами, объединяюшая их в единое целое (пренебрежем защитой данных и явным конструктором):
type Person = class // оболочка Name: string; Age: integer; procedure Print; begin writeln(Name,' ',Age); end; end;
Это целое является типом, которым можно пользоваться как обычным типом: описывать переменные этого типа (объекты) и пользоваться ими, используя точечную нотацию для вызова этих подпрограмм (методов) и обращения к этим переменным (полям). Только сконструировать эту переменную надо перед первым использованием:
var p: Person := new Person; // Сконструировать новый объект - обязательно p.Name := 'Иванов'; p.Age := 18; p.Print;
Все просто. Такой способ изложения позволяет рассказывать о классах практически сразу после темы "Подпрограммы".
Еще можно добавить, что внутри класса можно написать свой метод-конструктор с параметрами:
constructor (nm: string; ag: integer); begin Name := nm; Age := ag; end;
Да-да, в PascalABC.NET имя можно не добавлять. Но если уж добавили - помните: все конструкторы в PascalABC.NET должны именоваться Create. Тогда предыдущий код упростится:
var p: Person := new Person('Иванов',18); p.Print;
2. При написании кода программы на доске (да-да, еще кое где все еще пишут на доске!) гораздо проще описывать методы класса сразу.
И еще одно маленькое замечание. Если уж так страшно использовать конструкторы классов, можно воспользоваться записями - в PascalABC.NET в записях тоже могут быть методы и они могут описываться внутри. Повторим предыдущий ко для записей для лучшей обозримости:
type Person = record Name: string; Age: integer; procedure Print; begin writeln(Name,' ',Age); end; end; var p: Person; begin p.Name := 'Иванов'; p.Age := 18; p.Print; end.
31.08.25. Вышла версия PascalABC.NET 3.11, ориентированная на многоязыковость. В нее встроен компилятор языка SPython (расширение .pys)
20.02.25. 28 – 29 марта 2025 г. Институт математики механики и компьютерных наук ЮФУ проводит пятую онлайн Всероссийскую научно-методическую конференцию «Использование системы программирования PascalABC.NET в обучении программированию». Зарегистрироваться на конференцию можно здесь.
16.02.25 состоялась первая олимпиада на языке программирования PascalABC.NET среди учеников компьютерной школы мехмата ЮФУ. Опубликованы разбор задач 1 ступени и разбор задач 2 ступени.
07.01.25. Опубликован обзор языка Learn PascalABC.NET in Y minutes.
02.01.25. Вышла версия PascalABC.NET 3.10.2. Основное: константы [1,2,3] по умолчанию считаются массивами.