![]() |
|
Модераторы: korob2001, ginnie |
![]()
|
|
| Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
Вообщем-то раньше писал на яве, сейчас пишу на перле, но очень хочется порой писать по ООП'ному, просто так красивее и проще
Просмотрел ряд топиков, но все же... Хочется решить такую задачу: Есть класс, в нем инкапсулированные переменные класса, и методы getVariable1, getVariable2 и т.д., а также методы setVariable1, setVariable2 и т.д. Все переменные должны поступать через конструктор класса, т.е. методы setVariable1 и т.д. только для правки. Т.е. по сути дела класс - лишь контейнер для хранения данных. Далее каждый экземпляр класса должен хранится в массиве, и при необходимости получать ту или иную переменную через метод getVariableX, соотв. для этого он и задумывается Вообще видел один не плохой топик, однако то, что меня в нем не устроило, то, что там массив был внутри самого экземпляра класса. Мне же нужно чтоб класс был лишь "контейнером". Т.е. каждый экземпляр класса хранить по одному набору переменных объявленных в классе. А все экземпляры класса хранятся в массиве, скажем так основного скрипта. При прохождении данного массива обращаемся каждый раз к очередному экземпляру класса и работаем с переменными из данного экземпляра... Надеюсь понятно выразился... -------------------- менеджер по кодеврайтингу |
|||
|
||||
| korob2001 |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2871 Регистрация: 29.12.2002 Репутация: 31 Всего: 61 |
Ну насколько я понял, нужно что-то типа этого:
Есть класс Person, поля которого хранят имя, фамилию и возраст человека. Опишем его: Файл Person.pm
Теперь сохраним в тот же каталог, файл который будет использовать наш класс Person. Файл people.pl
Я для краткости, не стал использовать все методы, но ты если хочешь можешь опробовать и их, но тогда последний цикл тебе придётся заменить, так как в нём массив очищается, так как используется как стёк, т.е. вместо строки:
Вставь наример такую:
После этого цикла все объекты так и будут храниться в нашем массиве @people и будет возможность поэксперементировать с ним ещё. Например можно попробовать добавить каждому человеку не по одному году, а по 5 лет используя всё тот же метод addAge() но уже с одним параметром типа int.
Здесь параметры получаемые конструктором получились именованные, если же хочешь сделать так, как в Java, то в конструкторе используй анонимный массив вместо анонимного хеша. Но это так, простейший пример, если хочешь более подробно, то поищи в разделах по Perl, по ключевому слову "ООП" или "Объектно Ориентированное Программирование", а так же советую почитать книгу "Программирование на Perl", в ней автор языка более подробно описывает данную тему. Если знаком с Java, то думаю всё будет понятно. Это сообщение отредактировал(а) korob2001 - 1.10.2007, 21:06 -------------------- "Время проходит", - привыкли говорить вы по неверному пониманию. "Время стоит - проходите вы". |
||||||||||
|
|||||||||||
| Bulat |
|
||||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
korob2001, супер.... Это даже больше чем я ожидал...
Есть только пара вопросов, чтоб добить это
Я так понял, объявление переменных внутри класса, инкапсулирует их ??? И как бы так грамотнее выразится... $self и будет являтся экземпляром класса ??? И послдений пока вопрос:
немного напоминает объявление массива хэшэй, но суть вопроса не в этом.... Как правило в яве, вроде бы и в С++, в конструкторе мы пишем все входные параметры, а при создании очередного экземпляра класса, лишь пишем, допустим $name = "Вася" $family = "Пупкин" $age = 16 new Person($name, $family, $age) и тут главное соблюдат правильную последовательность переменных... При таком объявлении, возможно не соблюдение последовательности ??? Добавлено через 13 минут и 32 секунды Млин, прям все это так глаз радует, все эти старые геттеры и сеттеры, методы и классы, и все на перле..... Море восторга, и соотв... -------------------- менеджер по кодеврайтингу |
||||
|
|||||
| Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
М-дя, и в догонку очень важный вопрос о деструкторах... В яве-то их ручками писать не надо, а как насчет перла ??
-------------------- менеджер по кодеврайтингу |
|||
|
||||
| nitr |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2543 Регистрация: 10.2.2006 Где: Россия :) Репутация: 37 Всего: 84 |
Bulat, тоже самое "не надо", но это исходя из задачи. В данном примере - не нужен.
А korob2001 как всегда |
|||
|
||||
| Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
nitr,
А хорошего ;) , ресурса про ООП в перле случаем нет... А то в рамках данного примера все гуд, вот только хотелось более полно догнать такие вещи как наследование, инкапсуляция и т.п. P.S. Ссылки на топики форума прошу не кидать, в целом почти все промсотрел, но хотелось бы более полного материала -------------------- менеджер по кодеврайтингу |
|||
|
||||
| cerf_machine |
|
||||||
![]() Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 12.2.2007 Где: тебя носило? Репутация: 1 Всего: 1 |
Инкапсуляции в перле нет. Т.е. в представленном выше примере можно обращаться к "свойствам" "объекта" напрямую:
Наследование в перле не использовал, но знаю, что оно тоже, к сожалению, псевдо, как и перегрузка операторов:( Реализуется через подключение базового класса в @ISA дочернего.
Ага. Но на самом деле $self - ссылка на хэш, связанная (blessed) с текущим пакетом (Person). Свойства же - на самом деле - ключи хэша.
Да, возможно. Это сообщение отредактировал(а) cerf_machine - 2.10.2007, 14:41 |
||||||
|
|||||||
| korob2001 |
|
||||||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2871 Регистрация: 29.12.2002 Репутация: 31 Всего: 61 |
Как сказал cerf_machine, инкапсуляция отсутсвует, как таковая, это философия Perl. Но, Perl позволяет сделать закрытость ещё более надёжную, чем другие языки программирования, разумеется, если это нужно. Например можно таким образом изменить класс Person, который я приводил выше.
Вот собственно мы и закрылись, теперь поля доступны только внутри файла Person.pm, т.е. мы получили private поля. Можно так же сделать и protected, ну или что-то похожее на protected поля в Java, если изменить условие в конструкторе:
на такое:
Т.е. напрямую к полям теперь можно будет обращаться только из текущего пакета или же из классов наследников. Можно так же реализовать и закрытые методы, опять же, если это нужно.
Абсолютно верно, потому использовать анонимный хеш гораздо удобнее, не следует думать о перегрузке конструктора. Если же хочешь создать аналог создания Java или C++ объекта, то вместо анонимного хеша используй анонимный массив: Вот так теперь будет выглядеть наш класс Person.pm
а вот программа, которая его использует:
Кстати, можно так же заюзать псевдо-хеш, хотя они сейчас помечены как depricated, но в Perl можно реализовать что-то похожее на псевдо-хеш вручную, а можно так же и не вручную, например заюзав прагму компилятора fields
В Perl сборка мусора происходит тоже автоматически, примерно так же, как и в Java, потому деструкторы нужно юзать, как сказал nitr, только в исключительных случаях. Это сообщение отредактировал(а) korob2001 - 2.10.2007, 20:09 -------------------- "Время проходит", - привыкли говорить вы по неверному пониманию. "Время стоит - проходите вы". |
||||||||||||||||
|
|||||||||||||||||
| korob2001 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2871 Регистрация: 29.12.2002 Репутация: 31 Всего: 61 |
Кстати, ты говорил, что знаком с Java. Вот я тут как-то приводил пример того, как можно создавать классы Java на лету, прямо из Perl программы, а после этого создавать объекты в Perl программе и работать с ними, как с родными Perl объектами. Это работает примерно так же, как встроенный код Assembler'a в программу C++.
Вот здесь можешь посмотреть этот пример. Кстати, таким же макаром, можно встраивать в Perl программу и код на C++, Assembler, Basic, да и многих других языков и не только языков. Вобщем если будет интересно, то поищи модули на cpan.org, по ключевому слову "Inline". Если ты под виндой, то можешь просто набрать в командной строке, такую команду: C:\>ppm s Inline Получишь список модулей, для встраивания кода других языков в Perl программу. Что бы установить модуль дай команду: C:\>ppm i Inline-Java Или другое имя модуля, вместо Inline-Java. -------------------- "Время проходит", - привыкли говорить вы по неверному пониманию. "Время стоит - проходите вы". |
|||
|
||||
| Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
korob2001, ну инкапсуляция перемнных в классе-контейнере, вообще очень важна, так как если в ходе работы программы у нас создается не один экземпляр класса, то потом при попытке получить доступ, может вообще такая путаница произойти.... Вообщем как-то было у меня один раз в яве, после чего даже не стал разбиратся, тут это для меня как бы аксиома
В целом огромное пасиба, за очень содержательные ответы... А ссылки на досуге обязательно почитаю, хотя в моей текущей конторе мы пишем исключительно на перле.. Да и раньше кода я комбинировал яву с перлом, то это были отдельные программы одной системы, как правило перл использовал за их регулярки... Если же внутри кода создавать, то я так понимаю, нужно будет устанавливать и виртуальную ява-машину, сейчас, я думаю мне этого никто не позволит сделать, в новой конторе я еще не набрал такого "веса" cerf_machine, тоже большой сенкс -------------------- менеджер по кодеврайтингу |
|||
|
||||
| cerf_machine |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 12.2.2007 Где: тебя носило? Репутация: 1 Всего: 1 |
Ух, ты Даже не думал, что можно связать с пакетом ссылку на функцию. Хотя это логично - перл крайне гибкий язык. korob2001, спасибо. Bulat, не за что;) |
|||
|
||||
| Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
К сожалению пока углубится особенно в ООП на перле нет времени...
Появился такой вопрос... При стандартном сеттере, если передаешь в качестве параметра не саму переменную, допустим $name = "Александр", а setName((shortName($name))); т.е., процедура shortName делает какие-то модификации с самой переменной... ?? -------------------- менеджер по кодеврайтингу |
|||
|
||||
| cerf_machine |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 12.2.2007 Где: тебя носило? Репутация: 1 Всего: 1 |
Не понял вопрос.
setName получит $_[0] => return-значение shortName. |
|||
|
||||
| Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
cerf_machine,
вопрос ты как раз понял и ответил на него Я лишь хотел убедится, что реально метод получит значение возвращаемое процедурой -------------------- менеджер по кодеврайтингу |
|||
|
||||
| korob2001 |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2871 Регистрация: 29.12.2002 Репутация: 31 Всего: 61 |
Ответ уже дали, но всё же решил привести ещё один пример, так на всякий случай
Теперь осталось запустить программу из командной строки и передать ей своёимя в качестве параметра. Причём, что бы налядно увидеть работу программы, имя должно быть в беспорядочном регистре, например так: dEnNiS. Если программа была запушена правильно, то регистр будет исправлен. Нас интересует строка:
Сначала передаём параметр функции lc(), она преобразует строку в нежний регистр, т.е. она возвращает строку "dennis" и тут же передаёт её дальше, функции ucfirst(), которая поднимает первый символ строки в верхний регистр и возращает результат "Dennis" и наконец предаёт отредактированное имя методу $person->setName(). Т.е. сначала выполняется самая внутренняя функция, это аналогично применению скобок для изменения приоритета арифметических операций. Тоже самое можно делать и с методами, добавим в код ещё две строки, теперь он выглядит так:
В строке:
сначала выполняется метод $person->getName(), он возвращает текущее имя "Dennis", это имя передаётся функции uc(), которая переводит верхний регистр всю строку "DENNIS" и в конце устанавливаем уже проеобразованное имя методом $person->setName(). Это сообщение отредактировал(а) korob2001 - 5.10.2007, 17:06 -------------------- "Время проходит", - привыкли говорить вы по неверному пониманию. "Время стоит - проходите вы". |
||||||||
|
|||||||||
![]()
|
| Правила форума "Perl" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |