Подтвердить что ты не робот

Наследование и видимость - PHP

Мне трудно понять, почему мы получаем вывод этого кода:

<?php

class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }

    public function testPublic() {
        echo "Bar::testPublic\n";
    }

    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}

class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }

    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}

$myFoo = new foo();
$myFoo->test(); 
?>

Итак, Foo расширяет Bar. $myfoo является предметом класса Foo. Foo не имеет метода, называемого test(), поэтому он расширяет его из своей родительской панели. Но почему результат test() -

Bar::testPrivate 
Foo::testPublic

Не могли бы вы объяснить мне, почему первый не Foo:: testPrivate, когда этот родительский метод переопределен в дочернем?

Спасибо вам заблаговременно!

4b9b3361

Ответ 1

Вероятно, потому что testPrivate, как уже упоминалось ранее, является частным методом и не будет наследоваться/перезаписываться наследованием класса.

На странице руководства php.net вы, вероятно, получили тот код, из которого явно указано, что We can redeclare the public and protected method, but not private

Итак, что именно происходит, следующее: дочерний класс не будет обновлять метод testPrivate, но вместо этого создает свою собственную версию в "области", если только дочерний объект. Поскольку test() определяется в родительском классе, он будет обращаться к родителям testPrivate.

Если вы переопределили функцию test в дочернем классе, она должна получить доступ к методу childs ? testPrivate().

Ответ 2

Члены

private не могут быть переопределены, только общественные и защищенные. Это означает, что на самом деле testPrivate отключен не, поэтому Bar не может его видеть и по-прежнему вызывает свой собственный testPrivate.

Ответ 3

Частные методы не видны никому, кроме класса объявления. Поскольку вы вызываете testPrivate из родительского класса, единственным способом, к которому он имеет доступ, является его собственное объявление метода. Таким образом, вы получаете результат, который видите. Однако если модификатор доступа был protected, то вы получите ожидаемый результат, так как защищенные методы видны во всей цепочке наследования.

Ответ 4

Потому что private означает private. Никакой другой класс, даже класс детей не знает о Bar::testPrivate() и поэтому не может переопределить то, о чем они даже не знают.

Вы можете использовать Foo::testPrivate() только внутри Foo. Потому что это то, о чем private.

Дополнительная информация: Странное поведение при переопределении частных методов

Ответ 5

Из manual:

Участникам, объявленным как private, может быть доступен только класс, который определяет член.

Поскольку ваша тестовая функция работает в баре базового класса, она будет обращаться к частной функции в своем классе.

Ответ 6

Это не специфично для PHP. Правила наследования требуют, чтобы защищенные и публичные функции были переопределяемыми. Частные функции имеют свой собственный масштаб и невидимы для обобщенного класса.

Ниже приведена аналогичная ситуация на Java, такой же результат:

Bar::testPrivate

Foo::testPublic

Кроме того, вы можете получить предупреждение

The method testPrivate() from the type Foo is never used locally    Foo.java    

так как скомпилирована Java.

public class Bar 
{
    public void test() {
        this.testPrivate();
        this.testPublic();
    }

    public void testPublic() {
        System.out.println("Bar::testPublic\n)");
    }

    private void testPrivate() {
        System.out.println( "Bar::testPrivate\n");
    }
}

public class Foo extends Bar {
    public void testPublic() {
        System.out.println("Foo::testPublic\n");
    }

    private void testPrivate() {
        System.out.println("Foo::testPrivate\n");
    }

    public static void main(String[] args) {
        Foo myFoo = new Foo();
        myFoo.test();
    }
}