Что эквивалентно виртуальным функциям c ++ в PHP? - PullRequest
9 голосов
/ 21 марта 2010

Это 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

Ответы [ 3 ]

18 голосов
/ 21 марта 2010

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

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

virtual void foo() = 0;

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

РЕДАКТИРОВАТЬ : относительно отредактированного вопроса

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() или нет, так как предполагаемый тип известен (программист явно предоставил его )

4 голосов
/ 28 ноября 2012

В примере не показан типичный шаблон специализации, где 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();
1 голос
/ 11 марта 2013

использовать статическое ключевое слово (php 5.4) не $ This-> мет () но Статическая :: мет ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...