开始oop php问题:做构造函数取代getter?

Joe*_*oel 5 php oop constructor

我正在学习本教程:http: //www.killerphp.com/tutorials/object-oriented-php/php-objects-page-3.php

首先,他让你在课堂上创建一个setter和getter方法:

<?php

class person{
    var $name;      

    function set_name($new_name){
        $this->name=$new_name;
    }

    function get_name(){
        return $this->name;
    }
}

php?>
Run Code Online (Sandbox Code Playgroud)

然后创建对象并回显结果:

<?php 
    $stefan = new person();
    $jimmy  = new person();

    $stefan ->set_name("Stefan Mischook");
    $jimmy  ->set_name("Nick Waddles");

    echo "The first Object name is: ".$stefan->get_name();
    echo "The second Object name is: ".$jimmy->get_name();

?>
Run Code Online (Sandbox Code Playgroud)

按预期工作,我理解.

然后他介绍了构造函数:

class person{
    var $name;

    function __construct($persons_name) {       
        $this->name = $persons_name;        
    }       

    function set_name($new_name){
        $this->name=$new_name;
    }

    function get_name(){
        return $this->name;
    }
}
Run Code Online (Sandbox Code Playgroud)

并返回如下:

<?php 

    $joel   = new person("Joel");

    echo "The third Object name is: ".$joel->get_name();
?>
Run Code Online (Sandbox Code Playgroud)

这很好,很有意义.

然后我尝试将两者结合起来并得到一个错误,所以我很好奇 - 是一个构造函数总是取代"get"函数?如果你有一个构造函数,在创建对象时是否总是需要包含一个参数?

给出错误:

<?php 
    $stefan = new person();
    $jimmy  = new person();
    $joel   = new person("Joel Laviolette");
    $stefan ->set_name("Stefan Mischook");
    $jimmy  ->set_name("Nick Waddles");

    echo "The first Object name is: ".$stefan->get_name();
    echo "The second Object name is: ".$jimmy->get_name();
    echo "The third Object name is: ".$joel->get_name();
?>
Run Code Online (Sandbox Code Playgroud)

Gal*_*len 6

它给你错误,因为构造函数需要参数.要使参数可选,请为其指定默认值

function __construct($persons_name=null) {
    if ($persons_name) {
        $this->set_name($persons_name);//use the setter in the constructor.
    }      
}
Run Code Online (Sandbox Code Playgroud)

这将现在奏效

$stefan = new person();
$stefan ->set_name("Stefan Mischook");
$joel   = new person("Joel Laviolette");
echo "The first Object name is: ".$stefan->get_name();
echo "The second Object name is: ".$joel->get_name();
Run Code Online (Sandbox Code Playgroud)


Lot*_*tes 5

构造函数用于初始化对象.面向对象编程的期望是对象不应该存在,除非它处于有效状态.例如,没有名字和姓氏的Person可能不被视为有效实体,因此在首次创建对象时,应使用构造函数中的名字和姓氏对其进行初始化.

您收到错误的原因是因为构造函数具有必需参数,因此您必须将参数传递给它.

PS我真的很讨厌面向对象编程的解释,试图使用类似"Dog is-a Mammal"的类比.你应该远离这些例子.他们真的没有在现实世界的编程中提供有用的信息,有时甚至会给学生一种错觉,他们理解如何使用他们所教的内容.

如果您正在寻找使用构造函数创建有效状态的对象的实际应用程序,请设想一个使用数据库进行持久化的博客文章.

例如,$BlogPost->save();如果没有首先使用对数据库的引用初始化博客,那么写一篇长篇文章然后调用就没有意义了.在这种情况下使用构造函数的应用可能是

$BlogPost = new BlogPost($Database);
Run Code Online (Sandbox Code Playgroud)

必须写下来是没有意义的:

$BlogPost->setDatabase($Database);
Run Code Online (Sandbox Code Playgroud)

每次你想用它做任何事情.也许你会忘记写一次,你会想知道你花30分钟写的帖子在哪里消失了.这是一个无效状态的例子.

这个想法是你在第一次初始化时包含了类所依赖的任何东西,而不是冒着对象处于无效状态的风险.

编辑:将"两个参数"更正为一个.

  • 这完全取决于您如何定义构造函数.function __construct($ persons_name)有一个变量,$ persons_name是参数.在我的例子中,我碰巧做了同样的事情,虽然你可以定义它有任意数量的参数(或没有). (2认同)