Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.03.2008, 09:21   #1
Римма
Пользователь
 
Регистрация: 06.12.2006
Сообщений: 31
Радость ООП

Привет всем. Не подскажите мне как исправить ошибки. Это по предмету «Объектно-ориентированное программирование». На тему «Взаимодействие классов на принципах композиции». Примером является создание структуру данных «Динамический список статических очередей». Я написала описание классов(Буду делать в Delphi):
Информационный класс:
TADS=class
private
FNumber:integer; // какая-то информация
public
constructor Create(NaveNumber:integer);
function GetNumber:integer;
function SetNumber(NewNumber:integer);
end;
Класс очередь:
TQueue=class
private
FQueue: array[1..10] of TADS; // статический массив объектов типа «информация»
FFirst,FLast:TQueue;
FCount:integer // число элементов в очереди(массиве)
public
constructor Create(NewQueue:TADS, NewCount:integer) ;overload;
function GetCount:integer;
function GetFirst:integer;
function GetLast:integer;
function Add(Item:TADS; Index:integer);
function Delete(Index:integer);
function SetCount(NewCount:integer);
procedure ShowAll;
end;

Класс элемента списка:
TListItem=class
private
FQueue: TQueue; // содержимое элемента списка(очередь)
FNext: TListItem;
public
function GetQueue:integer;
function SetQueue(NewQueue:integer);
function GetNext:integer;
procedure ShowAll;
end;

Класс списка:
TList=class
private
FFirst: TListItem;// показывает первый элемент списка
FCount1:integer; // число элементов
public
constructor Create(NewFirst: TListItem,NewCount1:integer);overlo ad;
function GetCount1:integer;
function SetCount1(NewCount1:integer);
function GetFirst:integer;
function Delete(Index:integer);
procedure Insert(Index:integer, NewQueue: TQueue);
procedure Open;
procedure Close;
procedure Save;
end;


Мне сказали ошибки есть. И даже сказали где мои ошибки:
1. В классе очереди свойства FFirst и FLast объявлены неправильно (очередь
реализуется на базе массива!)
2. В классе элементов списка нет конструктора
3. Для чего нужны методы типа ShowAll ?
4. Что это за методы Open и Close ?
5. Параметры некоторых методов продуманы плохо, при реализации это вылезет

И вы добрые люди не сможете показать как будет выглядеть описание классов если исправить ошибки. 2 и 3 я как бы поняла а вот остальные ошибки не как не могу сообразить, то есть не знаю как исправить. Методы Open и Close я использовала для того что для сохранения в файл и загрузка из файла. Если эти не используется а какой метод для этого предназначен то а? Я в инете пробовала искать электронные учебники че то не смогла найти хорошую. C НЕТЕРПЕНИЕМ жду ваших советов добрые люди. Заранее БОЛЬШОЕ СПАСИБО.
Римма вне форума Ответить с цитированием
Старый 12.03.2008, 09:59   #2
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Код:

//Информационный класс:
TADS=class
private
   FNumber:integer; // какая-то информация
   function GetNumber:integer;
   function SetNumber(NewNumber:integer);
public
   constructor Create(NaveNumber:integer);
   // Лучше сделать свойством
   property Number : integer read GetNumber write SetNumber;
end;


//Класс очередь:
TQueue=class
private
   FQueue: array[1..10] of TADS; 
   FCount:integer // число элементов в очереди(массиве)
public
   // Не очень хорошая идея добавлять элемент сразу в констракторе, 
   // но в принципе допустимо. Но вот количество меняется только 
   // при добавлении здесь его не указываем
   constructor Create(NewQueue:TADS);
   function GetCount:integer;
   // Лучше сделать два метода 
   // отедльно добавление, на что указывет название
   procedure Add(Item:TADS);
   // И отдельно вставка 
   procedure Insert(Item:TADS; Index:integer);
   // Раз уж это очередь, может сделать Push/Pop с обеих концов ?

   //
   procedure Delete(Index:integer);

   // Никаких изменений количества 
   // удалить 
   //function SetCount(NewCount:integer);

   // Проще возвращать сразу сам элемент
   function GetFirst:TADS;
   function GetLast:TADS;

   // В принципе можно и реализовать, например для 
   // отладки - просто отображение всей информации
   procedure ShowAll;
end;

Класс элемента списка:
TListItem=class
private
   FQueue: TQueue; // содержимое элемента списка(очередь)
   FNext: TListItem; 
public
   // Констрактор конечно нужен, но и дестрактор потребуется
   // Это относится и к другим классам
   constructor Create;
   destructor Destroy; override;

   // Если метод так называется, то должен возвращать TQueue
   // И лучше сделать свойством как показано выше
   function GetQueue:TQueue;
   function SetQueue(NewQueue:TQueue);

   // А это лишнее, поскольку открывает информацию о внутреннем строении
   // function GetNext:integer;

   // на ваше усмотрение
   procedure ShowAll;
end;

Класс списка:
TList=class
private
   FFirst: TListItem;// показывает первый элемент списка
   FCount1:integer; // число элементов
public
   // Опять-же кострактор должен быть без параметров
   // установка начальных значений - внутреннее дело объекта 
   // а не пользователя
   constructor Create(NewFirst: TListItem,NewCount1:integer);

   function GetCount1:integer;
   // GetCount еще можно реализовать, но никак не SetCount
   function SetCount1(NewCount1:integer);

   // Должен возвращать элемент, а не индекс
   function GetFirst:TListItem;

   // Удаление и вставка по индексу ?
   // Может тогда список реализовать по другому ?
   // Для используемого связанного списка это будет неэффективно
   function Delete(Index:integer);
   procedure Insert(Index:integer, NewQueue: TQueue);

   //procedure Open;
   //procedure Close;
   // Лучше реализовать чтение/запись в поток, тогда Open/Close не понадобится
   procedure Save(F:TStream);
   procedure Read(F:TStream)
end;
Когда разрабатываете, думайте о том, как это будет использоваться.
Напишите тестовые примеры. Например

Код:
var T:TADS;
T := TADS.Create(5);
N := T.getNumber;
T.getNumber(6);
Как-то не очень, нужно бы реализовать чтобы:

Код:
var T:TADS;
T := TADS.Create;
N := T.Number;
T.Number := 6;
alexBlack вне форума Ответить с цитированием
Старый 12.03.2008, 10:42   #3
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Римма Посмотреть сообщение
1. В классе очереди свойства FFirst и FLast объявлены неправильно (очередь
реализуется на базе массива!)
согласно синтаксиса все правильно, но по логике задачи они должны быть integer, т.е. индексы первого и последнего элемента в очереди
Цитата:
Сообщение от Римма Посмотреть сообщение
2. В классе элементов списка нет конструктора
ну так допишите
Цитата:
Сообщение от Римма Посмотреть сообщение
3. Для чего нужны методы типа ShowAll ?
4. Что это за методы Open и Close ?
это вы нас спрашиваете что делают методы ваших классов?)
Цитата:
Сообщение от Римма Посмотреть сообщение
5. Параметры некоторых методов продуманы плохо, при реализации это вылезет
ну хотя бы, если функция ничего не возвращает, то уж сделайте ее процедурой.
pu4koff вне форума Ответить с цитированием
Старый 12.03.2008, 11:14   #4
Римма
Пользователь
 
Регистрация: 06.12.2006
Сообщений: 31
Подмигивание

Большое спасибо что не оставили мой вопрос без ответа. АlexBlack
если у меня в дальнейшим будет вопросы можно будет у тебя спрашивать а? Pu4koff вот это:
1. В классе очереди свойства FFirst и FLast объявлены неправильно (очередь
реализуется на базе массива!)
2. В классе элементов списка нет конструктора
3. Для чего нужны методы типа ShowAll ?
4. Что это за методы Open и Close ?
5. Параметры некоторых методов продуманы плохо, при реализации это вылезет
Мне отправил преподаватель. Я сама подумала но особо не смогла исправить свои ошибки вот поэтому к вам обратилась.
Римма вне форума Ответить с цитированием
Старый 12.03.2008, 11:50   #5
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от Римма Посмотреть сообщение
АlexBlack
если у меня в дальнейшим будет вопросы можно будет у тебя спрашивать а?
Без проблем. Думаю и другие участники вам с удовольствием ответят
alexBlack вне форума Ответить с цитированием
Старый 12.03.2008, 11:56   #6
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

про очередь на основе массива. одного кол-ва элементов в очереди мало. надо хранить первый и последний элемент очереди. мы же добавляем элементы в конец очереди, а извлекаем из начала. поэтому может быть так:
__****___
где _ - свободные ячейки очереди, а * - занятые.
или так:
**_____**

метод вставки в очередь по идее не нужен, а сделать просто добавление в конец очереди и удаление из начала очереди и больше никаких модификаций. это же очередь. зачем нам ненужные функции. всё должно быть по делу.
ShowAll если по заданию не нужен, то лучше удалить наверно, ибо непонятный и ненужный функционал он в любом случае нести будет)
pu4koff вне форума Ответить с цитированием
Старый 21.03.2008, 09:56   #7
Римма
Пользователь
 
Регистрация: 06.12.2006
Сообщений: 31
Вопрос

Привет всем. Люди доброе подскажите-ка мне пожалуйста. В классе очереди надо свойства FFirst и FLast объявить. Если так написать код правильно будет.

TQueue=class
private
FQueue: array[1..10] of TADS;
FCount, FFirst, FLast:integer // число элементов в очереди(массиве)
public
constructor Create(NewQueue:TADS);overload;
destructor Destroy;override;
function GetCount:integer;
procedure Add(Item:TADS);
procedure Insert(Item:TADS; Index:integer);
function GetFirst:TADS;
function GetLast:TADS;
end;
А еще вот че alexBlack ты написал мне:
// Удаление и вставка по индексу ?
// Может тогда список реализовать по другому ?
// Для используемого связанного списка это будет неэффективно
function Delete(Index:integer);
procedure Insert(Index:integer, NewQueue: TQueue);
В списки удаление и вставка таким кодом производится ведь, или еще другие методы есть?
Римма вне форума Ответить с цитированием
Старый 21.03.2008, 11:32   #8
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
А еще вот че alexBlack ты написал мне:
// Удаление и вставка по индексу ?
// Может тогда список реализовать по другому ?
// Для используемого связанного списка это будет неэффективно
function Delete(Index:integer);
procedure Insert(Index:integer, NewQueue: TQueue);
В списки удаление и вставка таким кодом производится ведь, или еще другие методы есть?
Нужно просто рассматривать по отдельности интерфейс объекта и его реализацию.

Для первого пишем примеры использования (или хотя-бы представляем их себе). Сразу выявляются все проблемы. Например, для TList есть методы Delete, Insert. Это хорошо. А добавление в конец списка. Не лучше ли добавить еще и метод Add ? То-же с получением объектов из списка. Есть метод getFirst, а как получить остальные элементы ? Может нужен еще и метод items[index:integer] ? А не стоит ли вообще убрать метод getFirst ? Зачем отдельный метод для первого элемента ?

Как видишь больше вопросов, чем ответов. И только разработчик класса
может на них ответить.

То-же самое с реализацией. Можно по-быстрому ее сделать хотя бы в общих чертах. И опять возникнут вопросы. Причем, как правило, вопросы о том какого типа должна быть переменная не возникают. Вопрос в том какие переменные нужны. Например, те-же Fist, Last. Мне, например, даже в голову не пришло их вводить. То есть если было бы, например 1000 элементов, я бы так и сделал, но 10 элементов можно просто переместить и очередь всегда будет начинаться с 1-го элемента.
Что касается реализации динамического списка связанным списком элементов. Представь себе список из 100000 элементов. Единственный способ получить элемент с номером 100000 - пройти по всему списку. Поэтому я и написал о неэффективности выбранной реализации. С другой стороны, накладные расходы не так уж и велики. Особенно если учесть трудности с альтернативной реализацией.
Как пример можно посмотреть реализацию TList в VCL. Кстати, из этого
класса можно взять интерфейсную часть. Все эти методы Insert, Delete, Add. Как вариант можно написать класс динамического списка как обертку вокруг класса classes.TList, если это не противоречит ТЗ.


ИМХО нельзя просто сесть и правильно написать объявления всех методов класса. Нужно писать реализацию, пробовать разные варианты, посмотреть на использование этого класса.

ЗЫ. FFirst, FLast:integer объявлены правильно
alexBlack вне форума Ответить с цитированием
Старый 11.04.2008, 08:38   #9
Римма
Пользователь
 
Регистрация: 06.12.2006
Сообщений: 31
Вопрос

Привет всем. Это еще раз я вас беспокою. Я вот код написала.
Информационный класс:

type
InfoClass = class // Информационный класс
Private // закрытые переменные члены
Name : String[20]; // инфо поле
Public
Constructor Create(aName : string); // конструктор
Procedure SetName(aName : string); // методы доступа
Function GetName:string;
end;


Класс статического очереди на базе массива:

QueueClass = class // Класс очереди
private
Queue: array[1..10] of InfoClass ;
Count:integer; // число элементов в очереди(массиве)
First: QueueClass;
Last : QueueClass;
public
Constructor CreateA(); // конструктор вызывается при создании элемента списка
Function GetFirst: QueueClass;
Function GetCount:integer;
Procedure SetCount(aCount:integer);
Procedure AddItem(aName : string); // процедура добавления элемента
Procedure SetFirst(aFirst : QueueClass);
Function GetLast: QueueClass; //
Function DeleteItem:InfoClass; // процедура удаления
Procedure SetLast(aLast : QueueClass); // устанавл. последний элемент
end;
И здесь мне препод сказал что не правильно объявлены First и Last. Для реализации статического очереди надо объявить массив
и две переменные – указатель начала очереди First и указатель конца очереди Last.
И при каждом добавлении нового элемента переменная Last увеличивается на 1,
а при удалении на 1 увеличивается указатель First.
Еще удобно ввести переменную-счетчик(Count) числа элементов в очереди, с помощью которой легко отслеживаются состояния пустой и заполненной очереди.
Если отсюда сделать вывод то они должны быть объявлены как в маем коде то есть QueueClass . А препод говорит неправильно. А как правильно их объявить то не можете подсказать мне люди добрые объявить как integer что ли?
Римма вне форума Ответить с цитированием
Старый 11.04.2008, 08:59   #10
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Вообще-то преподы частенько гнут свою линию не в тему. QueueClass в принципе можно считать указателем.
Ну если ему так хочется поставь примерно так:
Код:
First: ^QueueClass;
Last : ^QueueClass;
Введи счетчик типа того как это сделано в TStringList.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц