Тайпхинтинг: интерфейс или типы объектов

  • Автор темы Автор темы zerkms
  • Дата начала Дата начала

zerkms

TDD infected
Команда форума
Тайпхинтинг: интерфейс или типы объектов

[Внимание: очень холиварный пост]

PHP:
<?php   

class a
{
    function foo()
    {
        return 'a::foo()';
    }
}

class b extends a
{
    function foo($arg)
    {
        return 'b::foo()';
    }
}

function c(a $obj)
{
    echo $obj->foo();
}

c(new a());
c(new b());

внимание вопрос: если тайпхинтинг лишь проверяет тип объекта (точнее - нахождение объекта в иерархии наследования ниже искомого), но не регламентирует протокол общения (интерфейс) - какой смысл в нём?

ps: об интерфейсах я знаю, мне интересно поведение именно приведённого выше кода.
 
я вроде как большой :) теоретик ооп но твой код нарушает принцип полиморфизма - один интерфейс - разная реализация
 
Sokil.Dmytro
угу. нарушает парадигму, но соответствует синтаксису. я уже сказал - что я знаю и умею интерфейсы.
тезис поста в том, что если тайпхинтинг, применённый к интерфейсу, свою работу выполнит - гарантирует работоспособность функции, то тайпхинтинг с именем класса совершенно бессмысленен.
 
я тебя сейчас через слово понимаю :) насколько я єто кашу понимаю, то тайпхинтинг указывает на то, что агрумент следует интерфейсу указанного класса. и если туда передать б который уже не следует интерфейсу а, будет ругань. так?
по моему он как раз и указывает, какой интерейс ожидается

а ты пытаешь б использовать как а, привязывая тип к аргументу. правильно вроде понял? :)
 
Sokil.Dmytro
конечно будет ругань.
а непонятки (у меня) из-за того, что тайпхинтить можно как интерфейсы и абстрактные классы (правильно), так и обычные классы. в случае последних - проверяется лишь вхождение в иерархию наследования. по факту - наследник может передекларировать метод как ему угодно, что поломает функцию с тайпхинтом.

какое поведение я бы ожидал от пхп: на этапе трансляции он выкидывает фатал или варнинг с указанием, что тайпхинтить можно интерфейсы или абстрактные классы.
всё: теперь работоспособность функции будет гарантирована самим ЯП.
 
так оно вроде и говорит
Strict Standards: Declaration of b::foo() should be compatible with that of a::foo()
не фатал правда но все же :)
 
php 5.2.8 не говорит такого с error_reporting (E_ALL | E_STRICT);
но с указанным стриктом в пхп.ини говорит :-)

согласен - решение...
 
человек, использующий статические языки, тоже может возмущаться, почему у него нет возможности в php указать жестко тип переменной
Кроме того, можно использовать вещи не по назначению (или просто не разумно). Но это не значит, что надо от таких вещей отказываться. При такой логике стоило было бы от наследования отказаться. eval и много другого
 
x-yuri
чушь. до того, как Sokil.Dmytro напомнил о стрикте - я вполне привёл "решение" для пхп, которое не ломало бы идеологии языка с слабой типизацией.

Кроме того, можно использовать вещи не по назначению (или просто не разумно).
ЯП может и должен ограничивать это.
 
если использовать вещь не по назначению, то в будущем можно иметь неприятности. вот забивал ты гвозди чугунным микроскопом, а его следующую версию со стеклянной ногой сделали. и все.
 
человек, использующий статические языки, тоже может возмущаться, почему у него нет возможности в php указать жестко тип переменной
да, не совсем удачная аналогия

но с
ЯП может и должен ограничивать это.
я не согласен. Что-то можно ограничить, что-то нельзя. Появились же почему-то динамические языки. Т.е. почему-то программисты решили убрать часть вроде бы полезных ограничений
 
x-yuri
Т.е. почему-то программисты решили убрать часть вроде бы полезных ограничений
их не убирали - их просто не добавили. основной тезис стартового поста: тайпхинтинг по классу не гарантирует ничего -> бессмысленен.
 
Кроме того, можно использовать вещи не по назначению (или просто не разумно).
я имел в виду, что всегда будут люди, которые будут использовать вещи не по назначению. Иногда это будет оправданно, но в большинстве случаев - нет

-~{}~ 13.01.09 01:55:

основной тезис стартового поста: тайпхинтинг по классу не гарантирует ничего -> бессмысленен.
хорошо, давай на этом и остановимся
 
Автор оригинала: zerkms
...основной тезис стартового поста: тайпхинтинг по классу не гарантирует ничего -> бессмысленен.
Не так: "тайпхинтинг по классу не гарантирует ничего, ибо наследник может изменить интерфейс".

ИМХО, нелогична именно смена интерфейса наследником. Сейчас насколько я помню есть два варанта поведения:
- методы, производные от абстрактных методов и методов интерфейсов, должны четко следовать интерфейсу
- методы, производные от методов обычных классов, и методов реализованных в абстрактном классе, могут его менять
 
korchasa
угу, и 2 поведение сопровождается выбрасыванием варнинга уровня E_STRICT. что хоть как-то ситуацию исправляет.
 
Все правильно. PHP сообщает об ошибке прогаммиста, но (и это в духе PHP) разрешает ему писать так, как ему хочется (при условии подавления E_STRICT на этапе компиляции: вызов error_reporting() непосредственно в скрипте не влияет на это поведение, что вполне логично)
 
crocodile2u
угу, логично, сразу не подумал, что включать рантаймно, когда уже всё оттранслировалось - поздно.
но странно, что в документации это не указано. или я снова проглядел?
 
korchasa

если вы меняеете интерфейс - вы не пользуетесь ооп, вы пользуетесь щедростью языка программирования
 
crocodile2u
Оп-па. Спасибо. Не знал, про то, что это работает на компиляции.

О сколько нам граблей прекрасных
Готовят тайны в РНР.

Sokil.Dmytro
Спасибо, я в курсе.
 
Сверху