PHP - OOP类扩展

Dan*_*sen 1 php oop

一直在寻找,但仍然找不到解决这个问题的方法.我的问题是我得到了这些代码片段(例子):

核心文件

class Core {
    public $DB = null;
    public $Handler = null;

    function run() {
        $this->DB = "somedatabase";

        include_once('handler.php');
        $this->Handler = new Handler;

        $this->Handler->run();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是helper.php示例

class Handler extends Core {
    function run() {
        echo "<pre>"; print_r($this); echo "</pre>"; die();
    }
}
Run Code Online (Sandbox Code Playgroud)

即使我在包含帮助程序之前定义了DB变量,那么它在辅助类中仍然是空的.它的定义是,但它是空的.这意味着它正确地不与Core类共享相同的内存.

请记住,它自己的Core类也是实例.

-

谢谢你的所有建议

编辑

PhpMyCoder做对了.感谢您详细而精心撰写的回复.两年多来,我一直认为PHP范围与JavaScript的范围相同或类似.现在我意识到,如果我扩展我的"核心"类,我会获得其中的所有方法和属性.但这些价值观对我的班级和我的班级来说都是私密的.

这很棒.终于我明白了.

Bai*_*ker 10

从我在这里收集的内容,您谈论的是公共实例变量.他们正在按照OOP的要求进行表演.每次用实例化一个类

$core = new Core();  // or
$handler = new Handler();
Run Code Online (Sandbox Code Playgroud)

他们每个人都在内存中获得一个新的空间来存储他们的实例变量.实例变量对于类的每个实例都是唯一的,如名称所示.因此,Core和Handler的两个独立实例不共享实例变量.但是,由于Handler扩展了Core,因此创建了两个Core实例.一个实例是我在第一行创建的实例.创建另一个,以便Handler可以在第二行上扩展它.这两个实例Core不是同一个对象.要在所有核心对象中使用相同的Core值,您需要使用静态(类)变量.

class Core {
    public static $hello = 'World';
}

var_dump(Core::$hello); //string('Word')
Run Code Online (Sandbox Code Playgroud)

在我的示例中,$hello通过范围解析运算符访问它将始终可供所有人使用::.所以,Handler可以与任何访问Core::$helloparent::$hello.如果你想只揭露这个静态变量Core和它的子类,那么你就需要使它protected和访问它从内部Coreself::$hello和它的子类有parent::$hello.

class Core {
    protected static $hello = 'World';

    public function sayHello() {
        echo 'Hello '.self::$hello;  //from within Core, access with `self`
    }
}

class Handler extends Core {
    public function myParentSays() {
        echo 'My parent says: Hello '.parent::$hello;
    }
}

$core = new Core();
$core->sayHello(); // 'Hello World'

$handler = new Handler();
$handler->myParentSays(); // 'My parent says: Hello World'
Run Code Online (Sandbox Code Playgroud)

有关static关键字范围解析运算符的更多信息,请查看PHP文档.


编辑
我相信你的困惑在于对继承如何在OOP中起作用的误解所以让我给你一个现实世界的例子.假设您为员工创建了一个类Employee.此类具有公共实例变量(即,可以访问的变量->),用于人员的名称.在PHP中,这将是:

class Employee {
    public $name;

    public __construct($name) {
        $this->name = $name;
    }
}     
Run Code Online (Sandbox Code Playgroud)

现在让我们创建一个新员工:

$tim = new Employee('Tim');
Run Code Online (Sandbox Code Playgroud)

假设我们需要一个新类Intern,它应该是子类Employee.这应该很容易:

class Intern extends Employee {
    public function makeCoffee(Employee $receiver) {}
}
Run Code Online (Sandbox Code Playgroud)

如果我们现在创建一个新的实习生,他的名字应该是时间,因为我们已经创建了另一个名叫蒂姆的员工吗?不,这没有意义.

$intern = new Intern();
var_dump($intern->name); //string(0) ""
Run Code Online (Sandbox Code Playgroud)

现在说设置名称是一个复杂而艰巨的过程,我们宁愿不必再次编码.通过对我们的Intern类进行一些修改,我们可以将名称设置保留为其超类Employee.

class Intern {
    public function __construct($name) {
        parent::__construct($name);
    }

    public function makeCoffee(Employee $receiver) {}
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以创建一个新的实习生并设置他或她的名字.注意其他员工如何保留他的名字.

$intern = new Intern('Something Forgettable');
var_dump($intern->name); // string(21) "Something Forgettable"
var_dump($employee->name); // string(3) "Tim"
Run Code Online (Sandbox Code Playgroud)

现在为什么这样?在OOP中,子类/超类是"是一种"关系.在Intern"是" Employee.在Intern具有完全相同的属性和方法的Employee,但因为每个InternEmployee是不同的,他们有自己的价值观,这些属性.

考虑到这一点,我建议你重新考虑你的课程策略.它是否真的有意义那HandlerCore?是否有意义那MainControllerHandler