我对C++和Java中的OOP非常熟悉,而且我对PHP中的OOP还很陌生,毕竟PHP声称支持OOP。我正在重构实习时给我的一些代码,我发现了以下PHP编码风格。
<?php
class A {
public function echoVar(){
$this->__();
echo $this->var;
}
}
class B extends A{
function __(){
$this->var = 1;
}
}
$v = new B();
$v->echoVar();
根据我使用C++,尤其是Java的经验,这甚至不会尝试编译,但在PHP中执行很好。我知道所有的语言都不一样,但为什么PHP支持这种风格。这种风格是好的还是坏的做法?这个OOP怎么样?
据我所知,以下是我认为此代码有问题的地方。
var
不是类B
的已定义属性,但已被访问并给定值- 超类
A
如何/为什么可以访问子类B
的方法__
而不进行强制转换或抽象 - 我会问
A
类是如何访问属性var
的,但属性本身是用魔法创建的。严肃地说,为什么它可以访问var
我是PHP的OOP新手,所以请帮我澄清这些事情。
这是一个不太好的编码示例。首先,我建议激活严格的错误报告(E_ALL|E_strict|E_NOTICE(。
-
如果一个以前没有声明过的类/对象属性被赋值,它将被创建为对象的公共属性。然而,在严格的错误报告中,您会收到一个E_NOTICE。
-
虽然
__
属于B
类,但当实例化B时,它可以从A调用。该方法未声明为public
/protected
/private
,因此默认情况下为public
,因此父母/子女以及外部都可以访问该方法。 -
当然,这通常是一种糟糕的编码风格,至少A会要求在具有以下行的子类中实现
__
:abstract public function __();
。 -
最后,但同样重要的是,函数名
__
违反了PHP约定,因为以两个下划线开头的方法是保留的。
我将PHP描述为一种在事情不清楚时倾向于做出假设的语言,而C++和Java则是迫使你明确地写出所有内容的语言,否则它们会抛出错误。
问题#1-在PHP中,您不需要明确地声明类属性,以便稍后能够分配它们,正如您所发现的那样。显然,如果您立即尝试在一个类中使用echo $this->var;
而不进行赋值,那么它将是未定义的。
问题#2-所以这个有点奇怪,但基本上,如果你从一个子类创建一个超类,并在该子类中定义的方法中调用一个方法,那么就会调用超类版本。因此,即使__()
没有在A中定义,它在B中定义,所以如果你创建了一个A对象,并调用echoVar();
,你会得到一条关于方法__((未定义的消息,你仍然可以在B类型的对象中调用echoVar();
,因为__();
是在那里定义的。
问题#3-与#2类似,即使在子类中使用,也将使用变量的超类版本。
然而,我个人会尽量不使用这种风格的编码。我相信你已经意识到了,让一个类依赖于它的超类不是一个好主意。最好明确声明这些事情。
至于OOP,您发布的代码主要使用对象,而不是自由浮动的函数或代码行。