Что эквивалентно виртуальным функциям С++ в PHP?

Is it abstract function xxx?

Я только что сделал тест, который, кажется, указывает, что частный метод тоже виртуальный?

class a {
 private function test()
 {
  echo 1;
 }
}

class b extends a {
 private function test()
 {
  echo 2;
 }
 public function call()
 {
  $this->test();
 }
}

$instance = new b;
$instance->call();

Выход 2


person user198729    schedule 21.03.2010    source источник


Ответы (3)


В PHP все не частные функции являются виртуальными, поэтому нет необходимости явно объявлять их виртуальными.

Объявление функции-члена как abstract просто означает, что базовый класс не может предоставить реализацию, но все производные классы должны. Определение метода как абстрактного аналогично выполнению следующего в C++.

virtual void foo() = 0;

Это просто означает, что производные классы должны реализовывать foo();

EDIT: относительно отредактированного вопроса

b::call() не может получить доступ к a::test(). По этой причине при вызове приватной функции будет вызываться только та, которая находится в классе, из которого она была вызвана.

EDIT: Что касается комментария:

(Из Википедии)

В объектно-ориентированном программировании виртуальная функция или виртуальный метод — это функция или метод, поведение которых может быть переопределено в наследующем классе функцией с той же сигнатурой.

Из-за идеи явного указания того, за что вы платите в C++, вы должны объявлять функции виртуальными, чтобы позволить производным классам переопределять функцию.

class Foo{
public:
    void baz(){
        std::cout << "Foo";
    }
};
class Bar : public Foo{
public:
    void baz(){
        std::cout << "Bar";
    }
};

int main(){
    Foo* f = new Bar();
    f->baz(); //baz is not virtual in Foo, so the output is Foo
}

Изменить базу на виртуальную

class Foo{
public:
    virtual void baz(){
        std::cout << "Foo";
    }
};
//Same Bar declaration

int main(){
    Foo* f = new Bar();
    f->baz(); //baz is virtual in Foo, so the output is Bar as it will call the derived function
}

Обратите внимание: если бы переменная f в приведенном выше примере имела тип Bar* или Bar, не имело бы значения, была ли Foo::baz() виртуальной или нет, поскольку предполагаемый тип известен (программист явно предоставил его)

person Yacoby    schedule 21.03.2010
comment
Спасибо за демонстрацию, теперь я понимаю, что означает виртуальный. Но можете ли вы также доказать это с помощью PHP? Потому что кажется, что в PHP невозможно преобразовать объект в базовый класс, другими словами, в PHP нет такого понятия, как виртуальный? - person user198729; 21.03.2010
comment
В php нет такого понятия как виртуальный. Или наоборот, каждый метод является виртуальным, поскольку реальная реализация просматривается во время выполнения. - person VolkerK; 21.03.2010
comment
Я думаю, что лучше думать, что в PHP нет виртуальной концепции, так как это невозможно сделать в этом языке:Foo* f = new Bar(); - person user198729; 21.03.2010
comment
Но у вас есть instanceof и возможность перезаписывать методы. - person VolkerK; 21.03.2010

В примере не показан типичный шаблон специализации, где b не нужно знать детали реализации call(), но он может указать, как должно быть выполнено test(). И, к сожалению, он возвращает 1. Однако, объявив функцию защищенной вместо частной, она будет работать так, как ожидалось.

class a {
    protected function test()
    {
        echo 1;
    }
    public function call() {
        $this->test();
    }
}

class b extends a {
    protected function test()
    {
      echo 2;
    }
}

$instance = new b();
$instance->call();
person Michael Will    schedule 28.11.2012

используйте ключевое слово static (php 5.4) не $this->meth(), а static::meth()

person KOLANICH    schedule 10.03.2013