ООП: объявление методов, оперирующих данными extends классов

Духовность™

Продвинутый новичок
ООП: объявление методов, оперирующих данными extends классов

Есть у меня код в базовом абстрактном классе:

PHP:
public function test()
{
    return $this->foo( $this->var );
}
$this->var -- переменная, которая объявленна в базовом, но данными наполняется только в extends классах.

Вопрос: допустимо ли так структурировать иерархии с точки зрения ООП, когда в базовом классе "используется" (т.е. не используется - просто описан механизм действий) переменная "из" подкласса?
 

AmdY

Пью пиво
Команда форума
Вопрос: допустимо ли так структурировать иерархии с точки зрения ООП, когда в базовом классе используется переменная "из" подкласса?
если вопрос стоит так, то - нет. родитель не должен ничего знать о потомках.
у тебя в абстрактном классе должны быть так же объявлены метод foo и атрибут var
 

Духовность™

Продвинутый новичок
у тебя в абстрактном классе должны быть так же объявлены метод foo и атрибут var
они объявлены, да. только var == null, а в подклассах var уже содержит конкретное значение. код на самом деле выглядит так:

PHP:
public function getHtml()
{
    $this->createDocObject();

    return $this->xml2html( $this->doc->saveXML() );
}
жалко. а как же тогда быть? просто не хочется плодить в каждом классе однотипные методы.
 

AmdY

Пью пиво
Команда форума
а, тогда ничего плодить не надо
createDocObject и xml2html - это объявляешь в абстрактном классе
doc тоже объявляешь там же, только следи за типом, он обязан поддерживать метод saveXML
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>в базовом классе используется переменная "из" подкласса
из абстрактного класса ты вообще ничего "использовать" не можешь,
можшь просто объявить все, что надо и связанное с этим
а "данными наполнять" можно только в дочернем в любом случае
AmdY, ты видел все классы или угадываешь?
 

x-yuri

Новичок
triumvirat если хочется "полное ООП", тогда абстрактные классы тоже использовать нельзя - только интерфейсы

жалко. а как же тогда быть? просто не хочется плодить в каждом классе однотипные методы.
обычно так и бывает, например: либо меньше кода, либо одной зависимостью меньше. Если зависимость не будет меняться, то какой смысл от нее избавляться? С другой стороны если не сложно избавиться от зависимости, то почему бы это не сделать. Решать тебе
 

fixxxer

К.О.
Партнер клуба
с точки зрения "полного ООП" любой написанный код говно ))

по теме, не вижу ничего предосудительного в таком подходе
 

Духовность™

Продвинутый новичок
grigori
да-да, абстрактный класс я не могу юзать. поэтому я и сделал этот класс абстрактным отчасти. так по теме что скажешь - айс или не айс?

с точки зрения "полного ООП" любой написанный код говно
почему?

-~{}~ 02.03.09 22:30:

либо меньше кода, либо одной зависимостью меньше
да где тут зависимости?
 

Lightning

Трудоголик
$this->var -- переменная, которая объявленна в базовом, но данными наполняется только в extends классах.
Вопрос: допустимо ли так структурировать иерархии с точки зрения ООП, когда в базовом классе "используется" (т.е. не используется - просто описан механизм действий) переменная "из" подкласса?
Так если ж $this->var объявленна в базовом классе, значит она вовсе не "из" подкласса.
Так что все тут нормально. Подобную практику встречал много раз. Сам 100 раз так делал )))

-~{}~ 02.03.09 23:24:

родитель не должен ничего знать о потомках
Если я объявляю абстрактный класс с абстрактными методами, то получается, что этот класс "знает", что у его потомков должны быть такие методы. Все-таки родитель может кое-что знать.
 

x-yuri

Новичок
потому что ООП-шность - далеко не единственный критерий. Ты, навреное, мог уже видеть этот весь из себя ООП-шный hello, world!

да где тут зависимости?
потомки требуют от базового класса наличия поля $doc

либо меньше кода, либо одной зависимостью меньше
точнее можно превратить зависимость с protected-доступом на зависимость от интерфейса (т.е. перести к более слабой зависимости). Но я тоже пока не вижу в данном случае ничего предосудительного

Так если ж $this->var объявленна в базовом классе, значит она вовсе не "из" подкласса.
Так что все тут нормально. Подобную практику встречал много раз. Сам 100 раз так делал )))
Если я объявляю абстрактный класс с абстрактными методами, то получается, что этот класс "знает", что у его потомков должны быть такие методы
он не то чтобы знает. Он задает (определяет) интерфейс. Т.е. потомки зависят от родителя, а не наоборот. Имелся в виду, как я понял, принцип инверсии зависимостей – зависимости внутри системы строятся на основе абстракций. Модули верхнего уровня не зависят от модулей нижнего уровня. Абстракции не зависят от подробностей
 

AmdY

Пью пиво
Команда форума
grigori
предполагаю.
$this->createDocObject(); - делает примерно $this->doc = new DOMDocument();
дальше вызывается $this->doc->saveXML(), который предположительно должен вернуть строку с xml, кстати, по Макконелу, это нужно вынести в отдельный метод
private function saveXML() { return $this->doc->saveXML(); }
дальше xml2html производит xslt преобразование
в итоге мы получили несколько методов завязаных на интерфейсе а-ля DOMDocument
поэтому нужно либо вводить интерфейс, либо делать методы неизменяемыми в потомках, чтобы гарантировать целосность.
 

Lightning

Трудоголик
он не то чтобы знает. Он задает (определяет) интерфейс. Т.е. потомки зависят от родителя, а не наоборот. Имелся в виду, как я понял, принцип инверсии зависимостей
Согласен. Смотря как понимать слово "знает" в отношении классов. Один класс не может знать что "внутри" у другого класса (даже если это его родитель), а может знать только его интерфейс. Поэтому я считаю, что слово "знает" следует понимать как "знает интерфейс". Когда класс объявляет абстрактные методы, получается, что он частично знает интерфейс своих потомков и может его использовать в своих методах. Это не значит, что он от них зависит, естественно.

Извините, если это оффтоп.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
я считаю, что абстрактный класс вполне может лишь назвать методы и поля, а в дочернем будет прописан весь функционал

на то он и "абстрактный", чтобы полагаться на дочерние классы в реализации функциональности

я обычно так делаю, когда нужно предусмотреть множество вариантов реализации, сохраняя единство API

например, в моем пакете gCURL используются обработчики ответа для обработки данных на лету
можно назначить обработчик HTTP-заголовков ответа, который определит имя метода-обработчика тела ответа

Если тебе нужна гибкость и возможность "на лету" определять обработчик XML в разных случаях жизни, почему нет?
 

AmdY

Пью пиво
Команда форума
[offtop]кстати, а где можно скачать свежие реализации gCURL, ты его как-то вылаживал, я скачал и использовал[/offtop]
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
AmdY, возможн, ты прав, но это выходит за рамки вопроса
если ты прав - согласен, type hinting тут нужен (я его в такой ситуации использую)

-~{}~ 02.03.09 23:18:

могу сборку сделать и выложить последнюю редакцию
я все хочу cURL Multi выложить - бомба :)
 

AmdY

Пью пиво
Команда форума
по моему это вообще ооп-задротство, сам бы реализовал это добротным говнокодом, чтобы работало. о гибкости нужно думать, там, где она понадобится сегодня-завтра, а не там где она _возможно_ понадобится.

grigori
это не срочно, главное не забудь анонсировать релиз.
 
Сверху