关于php:子类是否从父类继承私有成员?

Is subclass inherits private members from parent class?

本问题已经有最佳答案,请猛点这里访问。

我有两个与OOP继承对象相关的问题:

  • 第一种是根据以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class Test {

    private $name ="Youhana";

        function getPrivate(){
            echo   $this->name ;
        }

    }

    Class Test2 extends Test {

    }
    $obj2 = new Test2();
    $obj2->getPrivate();
  • 结果将是=>youhana,但这是如何工作的,尽管继承意味着成员是从父代克隆到子代的,所以如果这是正确的,子类中的代码必须像下面的逻辑一样:

    1
    2
    3
    4
    5
     Class Test2 {// simple imagination to the Test2 after extends Test CLass
          function getPrivate(){ //which must return null not the value of the private member.
            echo   $this->name ;
          }
    }

    参考手册

  • 第二个问题是考虑以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     Class Ex1{

        function checkClassName(){
            var_dump(__CLASS__);
        }
    }

    Class Ex2 extends Ex1{

    }


    $obj2 = new Ex2();

    $obj2->checkClassName();//how this will return EX1 although we invoked this function from the second object which after the inheritance will have a clone of public and protected members of the parent class?
  • 尽管我们从继承后将有一个父类的公共成员和受保护成员的克隆的第二个对象调用了该函数,但它将如何返回ex1?


    当你从一个超类扩展时,什么都不会被"克隆"。这是错误的看待方式。类基本上是用于创建实例的模板。

    超类中的private属性仅对该超类中定义的方法可见。这就是它被称为"可见性"的原因。

    创建子类时,private属性仍然存在。它们在子类中定义的方法中不可见。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    class Foo {
        private $x = 1;        
        public function check() {
            return $this->x;
        }
    }

    class Bar extends Foo {
        public $x = 2;
    }

    class Buz extends Foo {
        private $x = 3;
        public function check() {
            return $this->x;
        }
    }

    $n = new Bar;
    var_dump($n); /*
     object(Bar)#1 (2) {
       ["x"]=>
       int(2)
       ["x":"Foo":private]=>
       int(1)
     } */

    var_dump($n->check()); // int(1)

    $k = new Buz;
    var_dump($k->check()); // int(3)

    https://3v4l.org/kktd2

    当您扩展类时,您正在创建一个专门的子类型case,它应该仍然与原始超类兼容。与extend一起使用时,private的要点是定义不受行为变化影响的部件。

    至于__CLASS__,它是一个"魔力常数"(即,实际上不是常数ish),由访问它的上下文决定。它会给你一个类的名字,然后在里面写了__CLASS__

    不过,我不知道您试图用它做什么,因为您不应该在生产代码中使用它。


    我想解释一下克隆的概念。

    假设我们有classA3个属性:

    1
    2
    3
     - private int x
     - protected int y
     - public int z

    然后我们有一个从classA继承的ClassB

    在本例中,我们使用克隆作为结构克隆。意味着父类的所有属性和方法都克隆到子类中。我们可以通过获取子类实例的大小来证明这一点。

    但是,他们的访问策略。这是OOP中的封装。

    ClassB具有xyz属性。但它不能访问x。(因为封装)

    结构克隆概念在运行时非常重要。在运行时,子级和父级之间没有任何关系。克隆到子级的父级的所有结构。在子类中,我们可以使用EDOCX1、14(在Java)和EDCOX1、15(C中)等关键字来访问这个克隆部分。

    最后,如我所说,在儿童班,我们有家长班的私人成员。我们可以通过语言提供的关键字访问它们。但是,由于封装原理,我们不能访问私有空间。