ООП именно в среде FreePascal[Решено]

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

ООП именно в среде FreePascal[Решено]

Сообщение tech » 07.04.2011 12:07:27

Не могу найти описании ООП для среды FreePascal. Везде или Delphi или Lazarus.
То, что слово Class надо заменить на Object выяснено.
Теперь не получается с Constructor и созданием объектов.

Приведите, пожалуйста, пример маленькой программы для FreePascal, где есть класс и создается объект.
Или ссылки, где можно посмотреть.
Спасибо.
Последний раз редактировалось tech 10.04.2011 00:51:18, всего редактировалось 1 раз.
tech
незнакомец
 
Сообщения: 8
Зарегистрирован: 10.10.2010 13:05:20

Re: ООП именно в среде FreePascal

Сообщение Mr.Smart » 07.04.2011 13:20:50

tech, читаем вот эту книжку.
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: ООП именно в среде FreePascal

Сообщение Vadim » 07.04.2011 14:03:24

tech писал(а):То, что слово Class надо заменить на Object выяснено.

Не надо.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: ООП именно в среде FreePascal

Сообщение Maxizar » 07.04.2011 16:35:48

Ну запугали парня...
То, что слово Class надо заменить на Object выяснено.


Нет тут ваша БОЛЬШАЯ ошибка. Просто есть путаница мол объект это нечто общее, скажем комплексное число (Реальная часть и мнимая). И чтоб этим всем, тобишь Re и Im манипулировать как одним целым, мы для себя как программисты создаем объект. Вы скажите зачем можно писать в лоб и все такое.. можно, но я вам сейчас покажу что так легче. Во-первых нужно понимать, что когда программой будут пользоваться другие люди и извините за выражение Им наср...ть как вы там что сделали главное чтоб она работала, но вот для Вас как программиста, это имеет значение. Далее я это покажу на примере.
Так вот Объект - нечто что можна рассматривать как одно цело (объект).

Но тип определенный вами может быть Object или Class или Record. и т.п. Ну вот в C++ путанице нет у них Object или Record = Структура.. а тут просто нужно понимать в каком случае слово Объект - это сущность (Комлпексное число, Точка, прямоугольник) а в каком случае Объект = Object - Тип данных, определяемый вами. Надеюсь хоть что то встало у вас на место в голове... Ну типа тоже самое про классы:
Класс комплексных чисел, и Вчера наша команда показала Класс (Слово одно а смысл ой ой ой...).
Тоже самое и между Object и Объект.. :!: :!: :!:


Как мы можем его реализовать(В смысле это комплексное число то есть нечто, которое в нашем мире является априори одной сущностью, которым мы и хотим манипулировать и на языке как одним целостным объектом...)? Так мы можем это дело записать(реализовать) Минимум тремя способами:
1 - Создать Запись Record:
Код: Выделить всё
TComplexRecord = Record
   Re:Real;
   Im:Real;
end; 


2- Cоздать Класс: Class:
Код: Выделить всё
TComplexClass = class
   private

   public
   Re:Real;
   Im:Real;

     constructor Create;
     destructor Destroy; override;
   end; 


3 - Создать Object:
Код: Выделить всё
  TComplexObject = Object
   Re:Real;
   Im:Real;
  end;   


Далее мы сможем это дело использовать так (пример грубый но в самый раз для понимания):
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
   CR:TComplexRecord;
   CO:TComplexObject;
   CC:TComplexClass;
   S:String;
begin
   CR.Re:=1;
   S:='CR.Re='+ FloatToStr(CR.Re);

   CO.Re:=2;
   [b][/b]S:=S+' CO.Re='+FloatToStr(CO.Re);

   CC:=TComplexClass.Create;
   CC.Re:=3;
   S:=S+ ' CC.Re='+FloatToStr(CC.Re);
   Caption:=S;
end;


Теперь по порядку:
Запись – самая простая реализация и самая быстрая!!! Именно по этому работу с комплексными числами я писал через запись :)
Почему быстрая потому что это кусок памяти с которым мы обращаемся как с одним целым (как с одной сущностью, что мы как раз и хотели) Теперь нас будет компилятор ругать если что то не так…

Класс- самый большой и не поворотливый, для его инициализации мы обязательно должны вызвать конструктор (всегда) потому что именно он выделит память в куче (ОЗУ) для его экземпляра. Для нашего примера, применение класса просто не оправданно, мы не используем наследование (явно) и тем более знаем что не будем порождать от комплексного числа что то еще… По этому вся мощь классов в данном примере просто лишняя, но можно делать и так.

Объект – это запись, НО с возможностью наследования и инкапсулирования (запихивания внутрь других методов) И так же возможность создавать различные области видимости полей. (По идее это то что в Делфи называется расширенная запись, в Free Pascal есть простая запись и Объект и самое главное классы :))

Конструктор для Объектов нужен только тогда, когда будут использоваться виртуальные методы и всякая крутость… После чего он будет почти одним и тем же, что и класс, НО с той оговоркой что он будет как и запись полностью располагаться на стеке. То есть Вы передаете экземпляр комплексного числа имеющего тип Объекта (не путать просто со словом Объект обозначающий сущность чего либо) в функцию, она функция (ну компилятор если быть точным) создаст локальную копию всего числа на стеке представьте что у вас полей не два (Re and Im) а скажем сотня.. вы все поля будите копировать ( ну не вы а функция не явно при каждом вызове).. Тогда когда Вы передадите такой же функции уже переменную которая явл-ся классом, то копий создано не будет, буедт лишь передан указатель на область памяти в котором лежит ваш экземпляр (конкретное число). В этом все плюсы и минусу каждого из возможных подходов к реализации через Классы или Объекты.

В данном примере который привел я, у меня для Объектов нет конструктора! Он нам не нужен, потому что мы не используем, виртуальных методов и всяких рюшек.. И в руководстве сказано, что если ничего такого нет (виртуальных методов бла бла) мы вправе не реализовывать конструктор. Что касается классов вообще, как написано в руководстве языка Free Pascal да и других скажем Delphi, конструктор должен вызываться всегда… вы захотите опровергнуть, что мол если не задать его, а сделать что то подобное:
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
   CC:TComplexClass;
   S:String;
Begin
S:=’’;
   CC.Re:=3;
   S:=S+ ' CC.Re='+FloatToStr(CC.Re);
   Caption:=S;

end;   


То все вроде работает, Да но ходить по лезвию и пользоваться этим нельзя… Для классов всегда нужен Конструктор и для каждого Экземпляра его нужно вызвать. Именно так и написано в руководстве по FPC.

Не могу найти описании ООП для среды FreePascal. Везде или Delphi или Lazarus.


Среды FreePascal нет! Это язык программирования такой.. он так и называется Free Pascal.
описании ООП – Это один из подходов программирования, который заключается в том что мы начинаем манипулировать не битами или цифрами, а именно объектами (отдельными сущностями) скажем кнопка… Если этого бы не было, вы бы сидели и обращаясь к видеобуферу через видеокарту и т.п рисовали эту кнопку вручную (ну я грубо, так что прошу прощения у более опытных).

По этому сущность ООП можно вообще прочитать в книгах хоть по С++.

Вот Lazarus – это среда быстрой разработки, которая работает с компилятором языка Free Pascal. По этому любая книга по Лазарусу, в ней будет описан язык ФриПаскаль, и собственно ООП для этого языка. Так же подойдет любая книга по Делфи.

Просто поймите ООП – это подход, (скажем копать яму руками или лопатой и все).
Другой вопрос реализации этого подхода в языке, так вот в делфи и фрипаскале если не брать деталей все один в один, даже более того скажу в языке С++ такая же песня, там просто будут отличия в уничтожении классов при выходе из видимости переменной, автовызов конструктора и всяких рюшек….
Вам дали книгу по Паскалю, все же порекомендую вот эту, лично ее читал, так же можно прочитать это дело в DRKB.

Теперь вообще лирика: А нафига это все нужно. Элементарный пример: берем теже самые комплексные числа, мы определим их через запись (Record), после чего мы создали наш пользовательский тип, язык фрипаскаль позволяет для типа данных переопределить стандартные функции и операторы скажем + - \ * и тп. Вплоть до exp.. – этой фигней вы будете страдать один раз при их реализации… вот мой модуль содержит почти все фунции вплоть до cosh и т.п… После чего вы можете писать что то в этом роде:

Код: Выделить всё
Var A,b,c,d,;
Begin
A:= sqrt(exp(b+c) / d * sin(b+1312));
End;


А вот теперь напишите тоже самое, через решения в лоб :twisted: , у вас будет для каждого числа Re и Im части. Откройте любой справочник по матану, и посмотрите как реализуется скажем деление… Вы скажите но ведь когда Мы будем переопределять все это дело при перегрузке операторов и функций будем делать тоже самое. Да НО мы это делать будем один раз ОДИН.. после этого мы будем писать как нормальные люди, как в Маткаде...

Ну думаю понятно объяснил :oops: :oops: ... про классы более подробно можно прочитать в любой нормальной книге, поверте если в книге написано не понятно или сложно про классы, поверте Автор ... и просто не берите эту книгу... :!:

PS. Так же подобные вещи обсуждались ТУТ(более внимательно читаем Ответы Сергея Горелкина :!: )
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: ООП именно в среде FreePascal

Сообщение vada » 08.04.2011 11:52:44

Объектами и классами ворочаю уже больше 20 лет, но более внятного, доходчивого и краткого описания еще не встречал!!!!
Уважаемый Maxizar, вам бы книжки писать. Я серьезно.

Добавлено спустя 4 минуты 23 секунды:
Кстати, направлять к С++ как к источнику высших знаний, я бы поостерегся. Более путаный язык еще поискать. Лучше JAVA. Правда там Объект это экземпляр Class-а :)
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: ООП именно в среде FreePascal

Сообщение tech » 08.04.2011 11:58:16

Требуется написать ООП-программКУ без графического интерфейса. Не нужны никакие кнопки и лишний код. Чисто демонстрация основных концепций ООП для учащихся 14-15 лет. Ничего лишнего и заумного. Назначение всех строчек кода должно быть ясно и понятно. Когда я выбираю "консольное приложение" в Lazarus, там появляется "куча кода". Поэтому пытаюсь написать во FreePascal. Информация о создании классов и их конструкторов смотрелась в книжках по Паскалю. Не получается.

Код: Выделить всё
type myclass = object {Если написать class, то не работает}
    a,b: byte;
    procedure print;
end;

{??? - КАК СОЗДАТЬ КОНСТРУКТОР КЛАССА}

{constructor myclass.create(a,b);         как в Delphi
begin a:=a; b:=b end;
end;}

{constructor myclass.init;                    как в Turbo
begin a:=c; b:=d end;
end; }

procedure myclass.print;
begin  writeln(a); writeln(b) end;

var obj: myclass;

begin
    {??? - КАК СОЗДАТЬ ОБЪЕКТ}

    writeln('­ Нажмите Enter');
readln;
end.

Исправьте, пожалуйста, кто-нибудь этот пример, чтобы создавался объект.
tech
незнакомец
 
Сообщения: 8
Зарегистрирован: 10.10.2010 13:05:20

Re: ООП именно в среде FreePascal

Сообщение Mr.Smart » 08.04.2011 12:18:32

Видимо плохо читали или не внимательно. В книге, на которую я скинул ссылку всё это разжёвано.
Код: Выделить всё
type

  pmyclass = ^myclass;
  myclass = object
     a,b: byte;
     procedure print;
     constructor Init(c,d: Byte);
end;

constructor myclass.init(c,d: Byte);
begin
  a:=c;
  b:=d;
end;

procedure myclass.print;
begin
  writeln(a);
  writeln(b)
end;

var obj: pmyclass;

begin
   obj:=new(pmyclass,init(1,2));
   obj.print;
   dispose(obj,done); 

    writeln(' Нажмите Enter');
readln;
end.
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: ООП именно в среде FreePascal

Сообщение daesher » 08.04.2011 12:20:41

tech писал(а):Требуется написать ООП-программКУ без графического интерфейса. Не нужны никакие кнопки и лишний код. Чисто демонстрация основных концепций ООП для учащихся 14-15 лет. Ничего лишнего и заумного. Назначение всех строчек кода должно быть ясно и понятно. Когда я выбираю "консольное приложение" в Lazarus, там появляется "куча кода". Поэтому пытаюсь написать во FreePascal.

Не обязательно: в Lazarus есть вариант "Программа". А лишний код можно и удалить.


Код: Выделить всё
{$ifdef fpc}{$mode objfpc}{$endif}//теперь все классы будут работать
{$ifdef MSWINDOWS}{$apptype console{$endif}//Теперь приложение точно будет консольным
uses Classes;
type myclass = class(TObject)
    a,b: byte;
    procedure print;
    constructor Create(a,b:byte);
end;

{??? - КАК СОЗДАТЬ КОНСТРУКТОР КЛАССА - очень просто, только нельзя забывать его определить в описании класса}

constructor myclass.create(a,b:byte);//         как в Delphi - а какая здесь разница?
begin
Inherited Create;//Не забываем!
a:=a; b:=b
end;


{constructor myclass.init;                    как в Turbo -  Можно и так, тогда надо оставить object(...)
begin a:=c; b:=d end;
end; }

procedure myclass.print;
begin  writeln(a); writeln(b) end;

var obj: myclass;

begin
    {??? - КАК СОЗДАТЬ ОБЪЕКТ}
   Obj:=MyClass.Create(2,3);
   Obj.print;
  Obj.Free;
    writeln('­ Нажмите Enter');
readln;
end.
daesher
постоялец
 
Сообщения: 221
Зарегистрирован: 09.03.2010 22:17:14

Re: ООП именно в среде FreePascal

Сообщение Vadim » 08.04.2011 12:26:37

daesher писал(а):type myclass = class(TObject)

Полностью согласен с докладчиком на счёт этого варианта создания класса. ;)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: ООП именно в среде FreePascal

Сообщение Odyssey » 08.04.2011 12:31:00

Как уже написал daesher, чтобы создать простую программу без графического интерфейса и без обработки командной строки в Lazarus, лучше выбирать "Программа" (Program). Тогда код получится примерно такой:
Код: Выделить всё
program Project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes
  { you can add units after this };

{$R *.res}

begin
end.

Из него можно смело убрать cthreads, если не нужна поддержка потоков, и комментарии. Ещё в параметрах проекта можно убрать значок программы и удалить ссылку на файл ресурсов. Если не пользуемся какими-нибудь классами из стандартной библиотеки, типа TStringList, можно убрать uses Classes. Тогда получится что-то типа:
Код: Выделить всё
program Project1;
{$mode objfpc}{$H+}
begin

end.

Если сильно мешает {$mode objfpc}{$H+} можно убрать и её, но тогда нужно убедиться, что в настройках проекта включено:
1) "Параметры компилятора" - "Режим синтаксиса (-M)" - "Object Pascal - по умолчанию (-Mobjfpc)"
2) "Параметры компилятора" - "Использовать строки Ansi (-Sh)".

Ошибки в вашем коде с class связаны скорее всего с тем, что консольная FP IDE устанавливает режим по умолчанию "fpc", а для классов нужен "objfpc" или "delphi". В Lazarus по умолчанию - "objfpc". Т.е. чтобы заставить классы работать в консольной IDE можно указать в исходниках {$mode objfpc} или {$mode delphi}.
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24

Re: ООП именно в среде FreePascal

Сообщение vada » 08.04.2011 12:38:07

Код: Выделить всё
type myclass = class(TObject)

Чёта я очкую, Славик. Думаешь прокатит?
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: ООП именно в среде FreePascal

Сообщение tech » 08.04.2011 12:40:39

Спасибо. Буду разбираться.
tech
незнакомец
 
Сообщения: 8
Зарегистрирован: 10.10.2010 13:05:20

Re: ООП именно в среде FreePascal

Сообщение Maxizar » 08.04.2011 16:54:44

vada писал(а):Объектами и классами ворочаю уже больше 20 лет, но более внятного, доходчивого и краткого описания еще не встречал!!!!
Уважаемый Maxizar, вам бы книжки писать. Я серьезно.

Ой Спасибо :oops: :oops: Возможно я когда нибудь задумаюсь над этим, просто Вы не первый кто мне об этом говорит, возможно у меня и правда получится... :D

Что касается С++ ну я просто не знаком с Java :evil: .

tech писал(а):Спасибо. Буду разбираться.

Если вопрос, для вас решен, то если не затруднит добавьте в заголовок темы (название темы) [Решено] Для этого нужно отредактировать самое первое сообщение нажав кнопочку правка... и изменить название темы (Старое название)+ ' [Решено] ';
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: ООП именно в среде FreePascal

Сообщение tech » 08.04.2011 22:52:27

Maxizar писал(а):Если вопрос, для вас решен, то если не затруднит добавьте в заголовок темы (название темы) [Решено] Для этого нужно отредактировать самое первое сообщение нажав кнопочку правка... и изменить название темы (Старое название)+ ' [Решено] ';

В принципе "да": чистый рабочий код получен. Правда только в Lazarus, хотя тут он даже выглядит нагляднее. Остался спортивный интерес: почему не работает во FreePascal?

Выше были приведены две варианта синтаксиса ООП на паскале. На картинке ниже убрано все "лишнее" и закомментирована нерабочая часть кода. В таком виде оба скрипта прекрасно выполняются в Lazarus, а первый еще и во FreePascal.
Изображение
  • [прог.1]Если раскомментировать строку obj.print, то выдается ошибка Illegal qualifier (неправильный спецификатор) - и в Lazarus и во FreePascal.
  • [прог.1]Если раскомментировать строку dispose(obj,done);, то выдается ошибка expression must be destructor call (выражение должно быть вызовом деструктора) - и в Lazarus и во FreePascal. Но если записать вот так - dispose(obj) - то работает.
  • [прог.2]Работает в Lazarus и не работет во FreePascal. В последнем ругается на слово class: identifier not found "class" (идентификатор "class" не найден).
tech
незнакомец
 
Сообщения: 8
Зарегистрирован: 10.10.2010 13:05:20

Re: ООП именно в среде FreePascal

Сообщение Mr.Smart » 08.04.2011 23:43:17

Ах да. В случае ООП в стиле Borlad Pascal.
Код: Выделить всё
obj^.print; { необходимо разименовать указатель }

В данном случае деструктор не реализован в объекте т.ч.
Код: Выделить всё
Dispose(obj);
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

След.

Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9

Рейтинг@Mail.ru