引擎盖下的传承

时间:2010-08-20 09:34:48

标签: php inheritance

所以,这是我最后一次唠叨继承的问题,所以我想继续问一下。所以我将在PHP中给出一个例子:

<?php

class Base
{
    private $z = 4;


    function GetPrivate()
    {
        echo $this->z;
    }

}

class Derived extends Base
{
}

$b = new Base();
$d = new Derived();

$d->GetPrivate();

&GT;

足够简单。当我一直读到关于继承的时候,解释只是“你继承了公众和受保护的成员”,就是这样。我没有得到的是关于这个例子中的解释器如何计算什么属于什么的一些事情。

例如,当创建派生类时,我能够使用Base的公共函数“GetPrivate”获取基类的私有变量。但是,继承的简单定义对我来说不起作用。我的意思是,我继承了GetPrivate方法,但我仍然只是从属于基类的那个方法得到私有变量的某种链接(即使$ this指的是派生类对象)。我无法在Derived类中创建一个新函数来访问这些私有变量。

因此,解释器是否会密切关注基类中继承的函数以及它们对仅对该基类可用的私有成员的可能链接?

3 个答案:

答案 0 :(得分:2)

答案很简单,请尝试一下:

<?php


class Base
{
    private $z = 10;

    public function getPrivate()
    {
        return $this->z;
    }
}


class Derived extends Base
{
    public function getPrivate()
    {
        return $this->z;
    }
}

$a = new Derived();

echo $a->getPrivate();

您现在已经看到我们已在getPrivate课程中定义了Derived,我们无法再访问z中的Base,因为如果我们想要能够从派生类访问它,我们需要声明它是受保护的而不是私有的。

答案 1 :(得分:2)

解释器(或其他OOP语言的编译器),一次检查一次访问。

当您致电$d->GetPrivate();时,解释程序会检查此主题中的上下文(公共上下文,因为我假设您不在DrerivedBase的相关班级中)和{ {1}}是一种公共方法。因此,在此上下文中允许GetPrivate(),因此没有错误。

$d->GetPrivate();中,上下文为GetPrivate()对象为$d,对Base的访问权限是当前对象(z)的私有元素。因此访问是有效的。

这里发挥的概念是'数据隐藏'(访问控制)和'封装'(数据和功能的组合)。

继承只允许使用$d GetPrivate() Base,因为它属于Derived的对象。

确实存在指向私有数据的链接,但该链接不是直接链接。重要的是访问发生在允许Base

所以回答你的问题是:

是!解释器会密切关注基类中继承的函数以及它们对仅适用于该基类的私有成员的可能链接。

希望这有帮助。

答案 2 :(得分:1)

好吧,我无法详细说明解析器的详细信息,但理解的关键在于理解visibility的含义:

  

声明为public的类成员可以随处访问。声明受保护的成员只能在类本身以及继承和父类中访问。声明为私有的成员只能由定义该成员的类访问。

Now, the PHP manual also states

  

例如,当您扩展类时,子类从父类继承所有公共和受保护的方法。除非某个类重写这些方法,否则它们将保留其原始功能。

如果您对派生类执行var_dump($d),则会看到它包含Base->z

object(Derived)#2 (1) {
  ["z":"Base":private]=>
  int(4)
}

因此在Base中有对z的引用,但它是私有的,因为私有意味着该成员只能由定义该成员的类访问,所以不能从Derived访问它。

通过在Base中提供公共方法来访问私有成员,您实际上是通过父方法控制访问。也许$z是必须在扩展类中只读的东西,例如数据库适配器。

这是信息隐藏和访问控制。这并不意味着,如果你扩展Base,你将失去$ z。继承是 is-a 关系。派生是-a Base,因此,它有一个$ z,虽然不是自身,而是通过它的父。

相关问题