| 
| 
 | Вопрос # 3 149/ вопрос открыт / | 
 |  Доброго времени суток, уважаемые эксперты!Я учусь писать классы, и возникли такие проблемы:
 
 1) Написал класс, по задаче (в приложении), возникает ошибка Stack overflow. Не могли бы вы объяснить, почему?
 2) Расскажите пожалуйста, как грамотно работать со свойствами классов (property)?
 3) Можете по-подробней рассказать про виртуальные и абстрактные классы а так же зачем используется reintroduce? Покапался в интернете, ничего полезно не нашел =\
 
 P.S: решение задачи мне не нужно, с этим я справлюсь и записями. Просто хотелось бы на примере этой задачи получше разобраться с классами. Заранее спасибо!
 К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса) Приложение:Переключить в обычный режим    program Project1; {$APPTYPE CONSOLE} uses  SysUtils; type TBenzinMark = 90..100;type TPriceType = 1000..3000; type TAZS = class    FCompany, FStreet: string;    FMark: TBenzinMark;    FPrice: TPriceType;    function GetMark: TBenzinMark;    procedure SetMark(aMark: TBenzinMark);    function GetCompany: string;    procedure SetCompany(aCompany: string);    function GetStreet: string;    procedure SetStreet(aStreet: string);    function GetPrice: TPriceType;    procedure SetPrice(aPrice: TPriceType);    //    property Company: string read GetCompany write SetCompany;    property Street:  string read GetStreet write SetStreet;    property Mark: TBenzinMark read GetMark write SetMark;    property Price: TPriceType read GetPrice write SetPrice; end; { TAZS } function TAZS.GetCompany: string;begin  Result:=FCompany;end; function TAZS.GetMark: TBenzinMark;begin  Result:=FMark;end; function TAZS.GetPrice: TPriceType;begin  Result:=FPrice;end; function TAZS.GetStreet: string;begin  Result:=FStreet;end; procedure TAZS.SetCompany(aCompany: string);begin FCompany:=aCompany;end; procedure TAZS.SetMark(aMark: TBenzinMark);begin FMark:=aMark;end; procedure TAZS.SetPrice(aPrice: TPriceType);begin FPrice:=aPrice;end; procedure TAZS.SetStreet(aStreet: string);begin FStreet:=aStreet;end; var A: TAZS; begin  try   a.SetMark(95);   a.SetCompany('Nubovoz');   a.SetStreet('Lolobasovo 8');   a.SetPrice(2500);    { TODO -oUser -cConsole Main : Insert code here }    writeln(a.GetMark);    readln;  except    on E:Exception do      Writeln(E.Classname, ': ', E.Message);  end;end. 
|  |   Вопрос задал: IlluminatI (статус: 2-ой класс)Вопрос отправлен: 3 сентября 2009, 19:07
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: Вадим К Здравствуйте, IlluminatI!Не знаю, каким образом возникла эта ошибка (она может возникать, я знаю когда, но в данном случае нет причин). Но есть другая проблема - конструктор класса надо вызвать. И свойства дергать правильно. То есть код как минимум должен выглядеть так
 
 try
   a := TAZS.Create;
   a.Mark := 95;
   a.Company := 'Nubovoz';
   a.Street := 'Lolobasovo 8';
   a.Price := 2500;
    { TODO -oUser -cConsole Main : Insert code here }
    writeln(a.Mark);
    readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;Само объявление тоже надо писать красиво, а то все свойства стали приватными:)объявление класса должно выглядеть где то так
 
 type
 TAZS = class
  private
    FCompany, FStreet: string;
    FMark: TBenzinMark;
    FPrice: TPriceType;
    function GetMark: TBenzinMark;
    procedure SetMark(aMark: TBenzinMark);
    function GetCompany: string;
    procedure SetCompany(aCompany: string);
    function GetStreet: string;
    procedure SetStreet(aStreet: string);
    function GetPrice: TPriceType;
    procedure SetPrice(aPrice: TPriceType);
    //
  public
    property Company: string read GetCompany write SetCompany;
    property Street:  string read GetStreet write SetStreet;
    property Mark: TBenzinMark read GetMark write SetMark;
    property Price: TPriceType read GetPrice write SetPrice;
 end;Цитата: Можете по-подробней рассказать про виртуальные и абстрактные классы
 
 Это долгий разговор, устану писать. Может учебник достать?
 
 Цитата: а так же зачем используется reintroduce Он обычно используется, когда надо перекрыть виртуальный метод предка, но поменять сигнатуру метода (кол-во и/или типы параметров). Обычно говорит о плохом дизайне и обычно он не нужен.
 
 Цитата: Расскажите пожалуйста, как грамотно работать со свойствами классов (property)? В коде выше есть все исправления для более грамотной работы. Есть вопросы - задавай, будем по одному.
 
|  | Ответ отправил: Вадим К (статус: Академик)Время отправки: 3 сентября 2009, 19:22
 Оценка за ответ: 5
 Комментарий к оценке: спасибо за разъяснения, но есть еще вопросы :) |  
 Мини-форум вопросаВсего сообщений: 11; последнее сообщение — 4 сентября 2009, 11:05; участников в обсуждении: 4. 
|   | IlluminatI (статус: 2-ой класс), 3 сентября 2009, 19:34 [#1]:Извините за названия - это я от фонаря писал, для проверки  . Stack overflow обычно при рекурсиях возникает, когда стэк переполняется? Может, посоветуете какой нибудь толковый учебник по классам? А то у меня "В.В. Фаронов - Delphi. Программирование на языке высокого уровня", а там про классы всего 4-5 страниц, и ни одного упоминяния про виртуальные и абстрактные. А насчет свйоств, я не совсем понимаю принцип их работы. Требуется вводить переменную и свойство, чтобы оформить свойство. Не проще ли обрящятся напрямую к переменной? например a.Company = 'lala'; чем писать два метода для нее? или я что-то недопонимаю %)
 |  
|   | Паровоз (статус: 10-ый класс), 3 сентября 2009, 19:45 [#2]:"Не проще ли обрящятся напрямую к переменной?" Проще, но не грамотно. Использование свойств позволяет отделить реализацию класса и его использование. В дальнейшем реализация может измениться, а использование будет тем же. Кроме того, такой подход позволяет помомо прямого чтения/записи выполнять дополнительные дейсвия, необходимые для поддержания нужной функциональнояти класса.
 |  
|   | IlluminatI (статус: 2-ой класс), 3 сентября 2009, 19:53 [#3]:Логично, но при кодинге, в списке (Code Helper или Code Complection вроде называется, точно не помню) появляется и переменная и метод. Это немного смущает, так как при работе со сторонними классами, я этого не замечал. Их как то можно скрыть или все таки я не внимательный?   |  
|   | Паровоз (статус: 10-ый класс), 3 сентября 2009, 20:52 [#4]:Рассмотрим пример. В интерфейсной части модуля unit1 пишем 
   TMy = class
  private
    Fx:Integer;
  public
    property x:Integer read Fx write Fx;
  end;В модуле unit2 используем unit1 и переменную ob типа TMy. Если Вы теперь напишите ob и поставите после него точку, то  Code Complection не покажет поля Fx. |  
|   | min@y™ (статус: Доктор наук), 3 сентября 2009, 21:15 [#6]:Могу тебе скинуть один свой интересный модуль. В этом модуле реализованы настройки некой моей программы (не важно, какой). Все настройки реализованы классами и сохраняются в XML (но это не важно). Ты этот модуль почитаешь (будешь читать-то?) и сразу поймёшь такие вещи, как полиморфизЬм и инкапсуляцЫя.
 В модуле полно комментариев. Скинуть тебе?
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | IlluminatI (статус: 2-ой класс), 3 сентября 2009, 21:36 [#7]:давай, буду очень благодарен |  
|   | min@y™ (статус: Доктор наук), 3 сентября 2009, 21:46 [#8]:Куды давать-то? Залезай ко мне в аську.
 Запросы авторизации у меня не принимаюццо, пиши сообщение и ответь на вопрос антиспам-бота. Если ответишь праильно, окажешься программистом по умолчанию. Это трудный вопрос для неподготовленных людей, но он отсеивает ботов, ламеров и блондинок. Кстати, абсолютно правильный ответ мне дала женщина лет 45-и.
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | Паровоз (статус: 10-ый класс), 3 сентября 2009, 22:15 [#9]:"абсолютно правильный ответ мне дала женщина лет 45-и" Посмотрел авторские данные min@y™:
 
 Q: Авторизуй меня в аське.
 A (для мущин): пожалуйста!
 А (для женщин): только после секса!
 
 |  
|   | min@y™ (статус: Доктор наук), 3 сентября 2009, 22:37 [#10]: Цитата (Паровоз): Посмотрел авторские данные min@y™:
 
 Это к делу не относится.
 Не перепутал - и то хорошо!
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | Вадим К (статус: Академик), 4 сентября 2009, 11:05 [#11]:Зачем заворачивают переменную в свойство с двумя методами? да все примитивно просто. Вот представим себе кнопку и свойство "надпись на ней". понятно, что если пользователь сменил его, то надо перерисовать кнопку. И если это была бы просто переменная, то отследить это изменение было бы очень сложно (конечно компилятор может отслеживать все это...). А если есть метод, то всё просто - метод может проверить новое значение, перерисовать, отослать администратору сообщение..., мало чего. Галочка "подтверждения прочтения" - вселенское зло. |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |