В чём выгода от использования :: для доступам к методам

hdd

Новичок
В чём выгода от использования :: для доступам к методам

Поясните на примерах для чего используют такой способ доступа к методам. Есть класс A, в нём метод MyMethod, его можно вызвать так:
$Object = new A();
$Object->MyMethod();

А можно так:

A::MyMethod(), но при этом все обращения к данным этого класса из метода через $this, придётся заменить на self::

В чём практическое приеимущество в использовании такого способа? Для чего удобнее его использовать?
 

AmdY

Пью пиво
Команда форума
$Object = new A();$Object->MyMethod(); - создал объект.
A::MyMethod() - объекта не создавал.
 

Vallar_ultra

Любитель выпить :)
hdd
$Object->MyMethod(); это вызов метода ОБЪЕКТА
A::MyMethod(); это вызов статической функции КЛАССА

В чём выгода от использования

Если надо использовать классы как пространства имён например(БИКРИКС делает именно так)
 

hdd

Новичок
а что неясно из документации?
В общем-то написал. Неясно в чём преимущество перед обычным способом, под номером 1.

$Object = new A();$Object->MyMethod(); - создал объект.
A::MyMethod() - объекта не создавал.
И что с того, что не создавал объекта?

В чём выгода от использования

Если надо использовать классы как пространства имён например(БИКРИКС делает именно так)
Можно подробнее? Когда это требуется, какие задачи решаются таким способом эффективнее?
 

Vallar_ultra

Любитель выпить :)
Знаешь что такое namespace?
так вот в РНР4 такой подход кое-как заменяет отсутствие пространств имён..... А зачем они нужны - на эту тему написаны тонны литературы
 

Alexandre

PHPПенсионер
$Object = new A();$Object->MyMethod(); - создал объект.
A::MyMethod() - объекта не создавал.
способ 1) создал объект, можно использовать другие методы этого объекта с данными объекта.
способ 2) объекта не создавал, используешь класс как набор функций, например определяешь класс работы со строками и используешь только отдельные функции, не создавая объекта STR::cut(), STR::dup() etc...

Вообще-то советую почитать
http://phpclub.ru/detail/article/oop-vs-proc
http://images.yandex.ru/yandsearch?text=%EE%E1%FA%E5%EA%F2%ED%EE-%EE%F0%E8%E5%ED%F2%E8%F0%EE%E2%E0%ED%ED%EE%E5+%EF%F0%EE%E3%F0%E0%EC%EC%E8%F0%EE%E2%E0%ED%E8%E5&stype=image
 

AmdY

Пью пиво
Команда форума
hdd, при создании объекта происходит парочка действий, например, выполняется конструктор, выделяется место под объект, это не всегда необходимо.
 

hdd

Новичок
Vallar_ultra
namespace по идее даёт возможность использовать методы и переменные, в зависимости от контекста.

В доке же по статическим методам сказано, что такой способ используется для возможности вызова методов, не создавая объект. Почему тогда все вообще методы так не объявить? И использовать только статические.

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

Чем, например, оправдано, их использование в том же битриксе?
 

Vallar_ultra

Любитель выпить :)
hdd
1) Ничем не оправдано [читай подпись]
2) Ты понимаешь разницу между понятиями КЛАСС и ОБЪЕКТ? только ответь честно =)
 

hdd

Новичок
Vallar_ultra
1) Если ничем не оправдано, зачем приводить его в пример :)
2) Класс - описание, объект - это конкретный экземпляр класса, обладающий описанным поведением.

Как это меня приближает к истине?

Alexandre, AmdY
Стало яснее, спасибо. Пока, кроме как хранилища методов, другого применения не увидел для этого.
 

Vallar_ultra

Любитель выпить :)
hdd
И не увидишь, ибо это основная область действия статических методов.

> Если ничем не оправдано, зачем приводить его в пример
Ты просил пример, я дал. Оправдан он или нет - это другой вопрос, и точки зрения могут быть оч. разными(эт я о том как работает Битрикс). Нужен актуальный - посмотри пристально на PEAR. для примера на Net_GeoIP
 

AmdY

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

Макс

Старожил PHPClub
hdd
Один из видов использования статических методов - всякие паттерны, порождающие объекты (Singleton, Factory Method и прочие): прямой вызов конструктора оборачивается статическим вызовом.
$obj = SomeClass::createObject();
 

aXis

Новичок
hdd

Практически вариант с созданием обьекта позволяет не описывать класс, а только заявлять интерфейс. То есть в любой момент мы можем подменить класс и никто не заметит. При написании большого проекта я тоже задавал себе такой вопрос. В итоге вообще заставляю себя избегать статик методов. А если приходится, то применяю опыт полученный при написании виндовс прог. То есть создается обьект Application который все инициирует, опрашивая все синглетоны и разбираясь кого вызвать и вызывая нужный модуль передает ему всю эту кучу или ссылку на себя. В итоге модуль не знает что за класс - главное что интерфейс нужный и все пашет. Даже если надо сменить синглтон, то делается это в одном месте.

Хотите примера? их есть у меня. Щас фреймворков развелось море. И ни один полностью не устраивает. В итоге всегда пишешь что то свое. А когда находишь готовое и лучшее начинаешь бегать и все менять. Вот я недавно внедрял систему привилегий в проект. А позже нашел хорошее решение (даже не ооп) в одном фреймворке. Выдрал нужные файлы, написал адаптер и в Application поменял одну строку - изменил имя. И все. И проект даже не заметил, что это даже не класс.

Конечно, некоторые скажут, что можно было и класс со статиками подменить. Однако этот класс используется не в одном проекте, поскольку является частью фреймворка. А за смену компонентов фреймворка я рискую получить по шее от коллег, работающих над соседним проектом.

Об этом написано тонны литературы, и на этом форуме тоже. И все равно пока сам на грабли не наступишь, спрашиваешь :).

зы: паттерны рулят. Всегда можно при некотором опыте избежать в коде явного создания обьекта и при этом использовать отложенную инициализацию его.
 

whirlwind

TDD infected, paranoid
2) Класс - описание, объект - это конкретный экземпляр класса, обладающий описанным поведением.
Не верно. Точнее - не полно из-за чего и неверно.

Класс - поведение, применимое к некоторому набору данных. Это поведение не имеет смысла без данных, так же как не имеют смысла и данные без какой-либо обработки.

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

Вызовы с :: не могут быть применены к экземпляру. Это значит, что они фактически не относятся к классу, хотя бы потому, что такой вызов не может обратиться к данным определенного экземпляра. Это обычная функция, реализованная в пространстве имен класса. Такие вызовы могут быть использованы только со статическими атрибутами, которые являются"глобальными" для всех экземпляров одного класса и наследников, но они не относятся к конкретному экземпляру.
 

aXis

Новичок
whirlwind

Абсолютно верно. Такое надо в faq.

Но возникает одна нехорошая трабла. При написании слабосвязанных модулей, каждый обьявляет интерфейс класса который ему нужно передать. И тут, увы, статик методы не работают. Приходится создавать обьект.
В пхп не требуют уточнения типов, однако выполнить статик метод передаваемого только по имени класса я не смог. И забросил эту идею - создаю объект. А что поделаешь.:( Иначе надо прописывать жестко класс - что абсолютно невозможно в \"кросс-проектных\" либах.

Конечно можно использовать имя класса как неймспейс. Тут уж кому как нравится. Зависит от человека и проекта. Если мы пишем для других программеров, всегда рано или поздно найдется чудик, который скажет - вот у меня есть класс и я хочу юзать его, а у вас вызовы через неймспейсы. Вы саппорт - разберитесь :). Возможна и обратная ситуация.

можно использовать рефлексию. Но это уже грузовик куда больший простого создания обьекта.

Плюс добавлю - насколько помню, статик методы не наследуются.

зы: лично я стараюсь избегать статик. Обусловленно это тем что время на написание создания обьекта куда меньше времени затраченного на мысли - а нужно ли будет в будущем наследование или подмена классов. Всего не предусмотришь.
Кстати в .net делается оба варианта классов :). Видимо задолбали их.
 

Активист

Активист
Команда форума
Если на примерах лучше, то можешь посмотреть следующий, видно разницу...

<?php
class api {
public function setReturnPath() {
$this->session['returnPath'][$this->mDir] = getenv('REQUEST_URI');
}
}


class module {
public $session;
public $mDir="moduleDir";

public function showReturnPath() {
echo $this->session['returnPath'][$this->mDir];
exit();
}

function __construct() {
global $_SESSION;

$this->session = &$_SESSION;
api::setReturnPath();
$this->showReturnPath();
}
}

?>
 
Сверху