我有两个与OOP继承对象相关的问题:
第一个是根据以下代码:
class Test {
private $name = "Youhana";
function getPrivate(){
echo $this->name ;
}
}
Class Test2 extends Test {
}
$obj2 = new Test2();
$obj2->getPrivate();
结果将是=> Youhana,但是这是如何工作的,尽管继承意味着成员从父级克隆到子级,所以如果这是正确的,子类中的代码必须像下面的逻辑:
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 ;
}
}
参考:Manual
第二个问题是考虑以下代码:
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,尽管我们从第二个对象调用了这个函数,继承之后将复制父类的公共成员和受保护成员?
答案 0 :(得分:2)
当你从超类扩展时,没有任何东西被“克隆”。这是看错的方法。该类基本上是用于创建实例的模板。
超类中的private
属性仅对已在该超类中定义的方法可见。这就是它被称为“可见性”的原因。
创建子类时,private
属性仍然存在。它们只是从子类中定义的方法中看不到。
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)
当你扩展一个类时,你正在创建一个专门的子类型 case ,应该仍然是compatible原始的超类。与private
一起使用时,extend
的要点是定义不会对行为进行任何更改的部分。
至于__CLASS__
,它是一个“神奇的常数”(暗示,实际上并不是常数),它由被访问的上下文决定。它将为您提供类的名称,然后在其中编写__CLASS__
。
虽然,我不知道你在尝试用它做什么,因为你不应该在生产代码中。
答案 1 :(得分:-1)
我想解释克隆概念。
假设我们classA
有3个属性:
- private int x
- protected int y
- public int z
然后我们有ClassB
继承自ClassA
。
在这种情况下,我们将克隆用作结构克隆。意味着父类的所有属性和方法都克隆到子类中。我们可以通过获取子类实例的大小来证明它。
但是,他们正在访问战略。这是OOP中的封装。
ClassB
具有 x
,y
,z
属性。但是无法访问到x
。 (因为封装)
结构克隆概念在运行时很重要。在运行时,在子级和父级之间没有任何关系。父母的所有结构都克隆到了孩子身上。在子类中,我们可以使用super
(在java中)和base
(在C#中)等关键字访问此克隆部分。
最后,正如我所说,在子类中,我们有父类的私有成员。我们可以通过语言提供关键字来访问它们。但是,由于封装原则,我们无法访问私有。