很抱歉这个混乱的标题,我找不到更好的标题。 我在PHP / 5.6.14上,我有这段代码:
class Base
{
private $foo; <--- NOTE
public function __construct()
{
$this->foo = "base foo";
}
public final function getFoo()
{
return $this->foo;
}
}
class Derived extends Base
{
public $foo; <--- NOTE
public function __construct($type)
{
parent::__construct();
$this->foo = "derived foo";
$this->somethingUndefined = "dynamically declared"; <--- NOTE
}
}
$base = new Base();
var_dump($base->getFoo());
$derived = new Derived(0);
var_dump($derived->getFoo());
$clonedDerived = clone $derived; <--- NOTE
var_dump($clonedDerived->getFoo());
运行最后一个getFoo()
会给我:
PHP注意:未定义属性:在C:.. \ test.php中导出:: $ foo line * getFoo()在基类*。
中实现的行
如果我将这三个条件放在一起,我会收到通知:
删除其中一个或多个会使通知消失。
这里发生了什么? $foo
不是静态的,并且不是未定义的......
我正在使用自定义error_handler将每个E_ALL变为异常,并且无法真正忽略此...
修改: 这只是我写的一个重现问题的例子,实际代码有很大不同。我不是试图暴露私人$ foo或其他东西。事实上,Base和Derived是由不同的开发人员创建的,他们为一个字段选择了相同的名称,并且这样做(以及其他两个条件)导致了Notice。我只是想了解为什么,因为AFAIK应该完全没问题。
答案 0 :(得分:1)
这是预期的行为,private仅表示此类。因此,子类不可见私有属性$foo
。将其更改为公开是不可行的,可能会有与您没有看到的相关的警告。报告给您的级别错误。
子类必须至少保持父级的相同可见性。
充其量你可以在子类中私有化,但这不会让你访问相同的$foo
注意与否,当试图强制私有变量成为别的东西时,代码的可读性很差。你期望得到哪个foo?如果您在父级中需要$foo
作为默认值,为什么不在其他名称中命名它,只需在子级的get方法中执行if / then。
基本上,当子类中的$foo
在父类中是私有的时,它会尝试更改它的值$foo
。然后从父级中检索它。正如我最多提到的那样,你不会得到你期望的 self.input_data = tf.placeholder(tf.float32, [None, config.n_steps, config.n_input], name='input')
# Tensorflow LSTM cell requires 2x n_hidden length (state & cell)
self.initial_state = tf.placeholder(tf.float32, [None, 2*config.n_hidden], name='state')
self.targets = tf.placeholder(tf.float32, [None, config.n_classes], name='target')
_X = tf.transpose(self.input_data, [1, 0, 2]) # permute n_steps and batch_size
_X = tf.reshape(_X, [-1, config.n_input]) # (n_steps*batch_size, n_input)
input_cell = rnn_cell.LSTMCell(num_units=config.n_hidden, input_size=3, num_proj=300, forget_bias=1.0)
print(input_cell.output_size)
inner_cell = rnn_cell.LSTMCell(num_units=config.n_hidden, input_size=300)
cells = [input_cell, inner_cell]
cell = rnn.rnn_cell.MultiRNNCell(cells)
,这会让代码混乱。
答案 1 :(得分:1)
我认为这是PHP中的一个错误,因为在PHP7中运行该示例不会产生此通知。更重要的是,如果您在var_dump($this)
定义中getFoo()
,则可以清楚地看到"foo":"Base":private
已定义,对象foo
的{{1}}也已定义, PHP&gt; = 7且PHP&lt; 7.请参阅:https://3v4l.org/Ob9m7
但是,我相信,无论你想用这段代码做什么,你都会采用错误的方式。正如ArtisticPhoenix已经提到的那样。我强烈建议你重新考虑并重新设计你正在做的事情。根据OOP,覆盖私有成员是不可能的。