Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中,是否可以用类属性中的子级替换父级?_Php_Oop - Fatal编程技术网

在PHP中,是否可以用类属性中的子级替换父级?

在PHP中,是否可以用类属性中的子级替换父级?,php,oop,Php,Oop,如果应用了多态性,则应该可以在任何位置用子对象替换父对象,因为子对象包含所有必需的属性。它始终满足父类接口。此外,它还可以扩展它 下面是一个非常简单的示例: class A { public int $x; } class B extends A { public int $y; } class C { public A $ca; } class D extends C { public B $ca; } $vd = new D(); $vd->cd

如果应用了多态性,则应该可以在任何位置用子对象替换父对象,因为子对象包含所有必需的属性。它始终满足父类接口。此外,它还可以扩展它

下面是一个非常简单的示例:

class A {
    public int $x;
}

class B extends A {
    public int $y;
}

class C {
    public A $ca;
}

class D extends C {
    public B $ca;
}

$vd = new D();
$vd->cd->x = 10;

echo $vd->cd->x;
错误:D::$ca的类型必须是A(与C类中的相同)


A
C
在库中,类
B
D
覆盖它们。

类型属性在PHP中是不变的

对于类型化属性,请从中选择:

属性类型是不变的。这意味着在继承过程中不允许更改(非私有)属性的类型(包括添加或删除属性类型)。如果父属性是私有的,则可以任意更改类型

属性类型不变的原因是它们既可以读取也可以写入。从int到?int的更改意味着从属性读取的内容现在除了返回整数外,还可能返回null。从?int到int的更改意味着不再可以将null写入属性。因此,逆方差和协方差都不适用于属性类型

您可以安全地做的是,在需要
A
实例的地方使用
B
实例:


C类{
公共服务A$ca;
}
$c=新的c();
$c->ca=新的B();

。。。因此,实现了“如果S是T的子类型,那么T类型的对象可以替换为S类型的对象”

我从未遇到过这样的问题,但读取错误消息可能是不可能的。您可以将属性设置为私有,并仅通过getter和setter方法授予访问权限。这样,您可以在设置属性时强制该属性是否符合您的条件。不管你想做什么,一定有更好的办法。如果您能详细说明为什么需要它,也许我们可以帮助您。旁注:您在示例中调用了
$vd->cd
,但是
$cd
在任何类中都没有定义。你的意思是使用
ca
而不是
cd
?实际上,类A和类C是库的一部分。A类为工厂,B类为单件。我需要用类D替换(扩展)类B。这可以通过用类C重载类A的get方法来实现。然后整个应用程序(库和应用程序)使用类D而不是B。这很好,但在类A和C中,不能为包含类C(D)实例的属性指定类型。然后写上面提到的错误。如果这个属性是私有的,库代码将使用类B的实例,应用程序将使用类D的实例。因此,它不是单例!