|
Вопрос # 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]:
Зачем заворачивают переменную в свойство с двумя методами? да все примитивно просто. Вот представим себе кнопку и свойство "надпись на ней". понятно, что если пользователь сменил его, то надо перерисовать кнопку. И если это была бы просто переменная, то отследить это изменение было бы очень сложно (конечно компилятор может отслеживать все это...). А если есть метод, то всё просто - метод может проверить новое значение, перерисовать, отослать администратору сообщение..., мало чего.
Галочка "подтверждения прочтения" - вселенское зло.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|