我是OOP的新手,发现它有用,发现它令人困惑。
我看了,我认为这必须是一个简单的问题,但搜索了“子类php的实例化”之类的东西,但却找不到任何关键点。
我想实例化一个对象,然后再实例化子类。我可以将子类“添加”到现有实例吗?
class Dog
{
protected $owner;
protected $color;
public function setOwner($owner)
{
$this->owner = $owner;
}
public function setColor($color)
{
$this->color = $color;
}
}
class Bulldog extends Dog
{
protected $name;
protected $typeOfTail;
... set tail....
public function setName($name)
{
$this->name = $name;
}
}
class Beagle extends Dog
{
protected $name;
protected $typeOfSpots;
... set spots ....
public function setName($name)
{
$this->name = $name;
}
}
$myDog = new Dog;
$myDog -> setOwner("Bob");
$myDog1 = new Beagle;
$myDog1 -> setName("name");
显然这不起作用,但如果我这样做
$myDog = new Beagle;
$myDog -> setName("name");
我认为只是将所有者设置为NULL?
有没有办法将类的现有值(或复制值)拉入子类的实例(我想我可以做一些复杂的方法来提取所有的值,但是有很多这些值....)这在PHP中很容易做到,还是我在LIMB上做了?
现在是凌晨3点30分,如果这真的很愚蠢,我会道歉,但是最近几天我遇到了障碍,而且我落后了。这似乎在当前项目中可能有用。
澄清:这是一个假设的例子。 (没有狗参与该项目。)假设我们有一只由Fred拥有的棕色狗,我们填充了dog
的一个实例(假装它是一个有很多进展的大班)。
第二天有人说“那条狗是比格犬”(稍后在文件中确定 - 这不是一个很好的例子)所以我们想要实例化一个名为Suki的Beagle
类。
我想要的是Beagle
的实例,它继承了已存在的 dog
信息。
再次抱歉。去睡觉了。
答案 0 :(得分:0)
一般解决方案:(如果您已经知道未来的子类)
直接创建子类的实例。您可以将它用作超类的实例。但是,有关您正在尝试实现的更多信息将非常有用。
所以它会像这样工作:
class Dog
{
protected $owner;
protected $color;
public function setOwner($owner)
{
$this->owner = $owner;
}
public function setColor($color)
{
$this->color = $color;
}
}
class Beagle extends Dog
{
protected $name;
public function setName($name)
{
$this->name = $name;
}
}
$myDog = new Beagle;
// here we call two methods of the Dog superclass
$myDog->setOwner("Bob");
$myDog->setColor("brown");
// now we call a method of the subclass
$myDog->setName("SomeName");
正如您所看到的,不需要再次将父类的方法添加到子类中。它们将被隐式继承,您可以在子类的实例上使用它们,就好像它们是在子类中定义一样。
如果省略其中一个方法调用,则属性将为null
,因为没有为属性分配默认值。
具体解决方案:(如果您不知道实际的子类)
如果无法直接创建子类,请创建如下构造函数:
class Dog
{
protected $owner;
protected $color;
public function __construct(Dog $dog = null) {
if ($dog) {
foreach ($dog as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
}
}
}
public function setOwner($owner)
{
$this->owner = $owner;
}
public function setColor($color)
{
$this->color = $color;
}
}
class Beagle extends Dog
{
protected $name;
public function setName($name)
{
$this->name = $name;
}
}
$dog = new Dog;
$dog->setOwner("Bob");
$beagle = new Beagle($dog);
$beagle->setColor("brown");
我没有测试代码,所以也许它还有一个bug,但它应该得到我的观点。
答案 1 :(得分:0)
家长和班级
您可以创建2个类,我们可以调用一个ParentClass
和一个ChildClass
。这给了我们:
class ParentClass
{
}
class ChildClass
{
}
如您所见,它们没有以任何方式,形状或形式链接,因此,我们需要扩展子类以使用父类,所以我们现在有:
class ParentClass
{
}
class ChildClass extends ParentClass
{
}
现在,孩子与父母交谈,所以让我们为父母添加一个属性,让我们称之为name
:
class ParentClass
{
protected $name; //Protected means it's private, but accessible to children
}
class ChildClass extends ParentClass
{
}
现在让我们为孩子添加一些功能,一个getter和一个setter:
class ParentClass
{
protected $name;
}
class ChildClass extends ParentClass
{
public function setName($value)
{
$this->name = $value;
}
public function getName()
{
return $this->name;
}
}
正如您所看到的,它使用了来自父级的$name
,这意味着孩子可以使用它的值,所以我们可以这样做:
$childClass = new ChildClass();
$childClass->setName("My Name");
print $childClass->getName(); // prints My Name
得到一个结果!
修改强>
额外显示二传手的区别:
class Dog
{
protected $owner;
protected $color;
protected $name; // I'd put this here as all dogs have a name, right?
// Put the getters in here as all they do is return, they won't change (hopefully...)
public function getOwner()
{
return $this->owner;
}
public function getColor()
{
return $this->color;
}
public function getName()
{
return $this->name;
}
}
class Beagle extends Dog
{
public function setOwner($val)
{
$this->owner = $val;
}
public function setColor($val)
{
$this->color = $val;
}
public function setName($val)
{
$this->name = $val;
}
}
/**
* Added extra code to setters
*/
class Dalmatian extends Dog
{
public function setOwner($val)
{
$this->owner = "Owner: " . $val;
}
public function setColor($val)
{
$this->color = "Color: " . $val;
}
public function setName($val)
{
$this->name = "Name: " . $val;
}
}
正如您在此示例中所看到的,有两个子类Beagle
和Dalmatian
,每个子类的值都有一些不同的设置器。
由于父类中的值不是静态的,因此每个子节点的值都不同,因此设置一个不会改变另一个,反之亦然。
要在所有子类中保留父级的值,请使用静态属性:
class Dog
{
protected static $owner;
protected static $color; // Don't know why you'd want this kept, but okay?
}
使用static::${variable_name};
拨打电话,而不是:$this->{variable_name};