我非常熟悉C ++和Java中的OOP,而且我是PHP的新手,毕竟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
,但属性本身是由 magic 创建的。严肃地说,为什么它可以访问var
。我是PHP的OOP新手,所以请帮我澄清这些事情。
答案 0 :(得分:1)
这是一个例子,嗯,不是那么好的编码。首先,我建议激活严格的错误报告(E_ALL | E_STRICT | E_NOTICE)。
如果之前未声明的类/对象属性被赋值,则它将被创建为对象的公共属性。但是,通过严格的错误报告,您将被抛出E_NOTICE。
虽然__
属于B
类,但是当实例化B时,可以从A调用它。该方法未声明为public
/ protected
/ private
,因此默认情况下为public
,因此父母/子女以及外部都可以访问。
当然,这通常是糟糕的编码风格,至少A会要求在子类中实现__
,并使用以下行:abstract public function __();
。
最后但并非最不重要的是,函数名__
是针对PHP约定的,因为保留了以两个下划线开头的方法。
答案 1 :(得分:1)
我会将PHP描述为一种在事情不清楚时倾向于做出假设的语言,而C ++和Java是迫使你明确写出所有内容的语言,否则它们会抛出错误。
问题#1 - 在PHP中,您没有明确需要声明类属性,以便稍后能够像您发现的那样分配它们。但显然,如果你在没有分配的情况下立即尝试echo $this->var;
类,那么它将是未定义的。
问题#2 - 所以这个很奇怪,但基本上,如果你从子类创建一个超类,并在子类中定义的方法中调用一个方法,超类版本将被调用。因此,即使在{A}中未定义__()
,它也在B中定义,因此如果您创建一个A对象,并调用echoVar();
,您将收到有关该方法的消息__()未定义,你仍然可以在B类对象中调用echoVar();
,因为那里定义了__();
。
问题#3 - 与#2类似,即使在子类中使用,也会使用变量的超类版本。
但是,我个人会尝试永远不要使用这种编码方式。我确信你已经意识到,让一个类依赖于它的超类是不是一个好主意。明确声明这些事情会更好。至于它是如何OOP,你发布的代码主要使用对象而不是自由浮动函数或代码行。