是否可以像在Java中一样访问PHP中的隐藏实例字段?

时间:2018-05-23 10:25:17

标签: java php

在Java中,在PHP中,在父类中声明的实例字段在子类中继承。因此,可以使用关键字this(在PHP中分配$this)来访问它们。

在Java中,如果子类碰巧声明了与父类同名的字段,则父类的字段是隐藏(请参阅JLS 8.3.1.1-3: Hiding of Instance Variables)。它就在那里,但如果子类想要访问它,则需要使用关键字super,如下例所示:

class Foo {
    protected int x = 1;
}

class Bar extends Foo {
    protected int x = 2;

    void somemethod() {
        System.out.println(this.x); // prints 2
        System.out.println(super.x); // prints 1
    }
}

请注意,我认为隐藏字段是一种不好的做法,因为它只会导致代码混乱并容易导致逻辑错误。最好不要声明与父类的实例字段同名的实例字段。因此,这个问题纯属学术性质。

尽管如此我很好奇:原则上可以在Java中访问隐藏的实例字段吗?是否可以将上面的代码片段翻译成PHP?

<?php

class Foo {
    protected $x = 1;
}

class Bar extends Foo {
    protected $x = 2;

    function somemethod() {
        echo $this->x, PHP_EOL; // prints 2
        //echo $parent->x, PHP_EOL; // doesn't compile... is there a way to do it?
    }
}

请注意,我在这里谈论实例变量。类(即静态)变量完全是一个不同的故事,不是这个问题的主题。

如果不可能:这是否意味着父实例字段在PHP中有效地被覆盖(而不仅仅是隐藏),因此无法访问?

1 个答案:

答案 0 :(得分:0)

这不适合你的原因是因为你压倒了父母。 Foo->$x在子范围内可用,因此当您在X中将2定义为Bar时,它会覆盖先前的设置变量。

如果你想要这样的东西像Java一样工作,那你就必须使用常量。

class Foo {
    const x = 1;
}

class Bar extends Foo {
    const x = 2;

    function somemethod() {
        echo parent::x; // prints 1
        echo self::x; // prints 2
    }
}

或者您只需更改Bar中的变量名称,然后您就可以通过继承直接访问它。