如何创建仅继承方法而不继承父属性的子类?

时间:2019-07-18 21:07:58

标签: php inheritance properties parent-child

假设我有以下代码:

首先,我创建了父母

 class Country {
  public $country;
  public $populationcountry;
  public $language;     

使用某些方法(与该问题无关)

public function function1() {   }
public function function2() {    }
             .
             .
                }  //end of parent class

然后我创建一个孩子

 Class city extends Country 
{
public $populationcity;
} 

然后创建对象(此示例中我仅创建了一个对象)

$city1 = new city();

$city1->populationcity = 10000; 

和对象数组

$cities = [$city1];    

最后,我只想“回声”孩子的财产(人口密度)

foreach ($cities as $city) {
foreach ($city as $k => $v) {
$city->populationcity;
echo $k . ': ' . $v . '<br>';
 }
}   

输出
人口城市:10000
国家:
人口国家:
语言:

我想保留父级的方法,但不保留父级的属性。我该如何实现?


David在评论中告诉我将属性设置为Private。我这样做了,但效果很好,但是当我创建Country对象时,它将在子类中打印父级的属性。

这是代码,当父属性为Public时,将为我提供此输出。

人口总数:10000
国家:
人口国家:
语言:
国家:英格兰
人口国家:30000
语言:英语

它应该打印:

人口总数:10000
国家:英格兰
人口国家:30000
语言:英语

当我将它们设置为“私人”时,我会得到:

致命错误:未捕获错误:无法访问私有属性国家:: $ C:\ xampp \ htdocs \ ejercicios.php:141中的语言堆栈堆栈:#0 {main}抛出了C:\ xampp \ htdocs \ ejercicios。第141行上的php

当我将它们设置为“受保护”时,我得到了:

致命错误:未捕获错误:无法访问受保护的属性国家:: $ C:\ xampp \ htdocs \ ejercicios.php:141中的堆栈跟踪:#0 {main}抛出了C:\ xampp \ htdocs \ ejercicios。第141行上的php

class Country {
  public $country;
  public $populationcountry;
  public $language;
  }

Class city extends Country 
{
public $populationcity;
}

$country1 = new Country();
$country1->language = 'English';
$country1->country = 'ENgland';
$country1->populationcountry = 30000;
$countries = [$country1];

$city1 = new city();
$city1->populationcity = 10000;

$cities = [$city1];

foreach ($cities as $city) {
 foreach ($city as $k => $v) {
$city->populationcity;
echo $k . ': ' . $v . '<br>';
}
}

foreach ($countries as $country) {
foreach ($country as $k => $v) {
$country->language;
$country->populationcountry;
$country->country; 
echo $k . ': ' . $v . '<br>';

}

}

2 个答案:

答案 0 :(得分:0)

看起来像一个错误的设计模式。对我来说,一个国家可以包含几个不同的城市。因此,城市不是国家。您的国家/地区实体类不应该是这样吗?

class Country
{
    /**
     * Collection of City objects
     * @var ArrayObject
     */
    protected $cities;
    protected $name;
    protected $population;
    protected $language;

    public function setCity(City $city) : self
    {
        if ($this->cities == null) {
            $this->cities = new ArrayObject();
        }

        $this->cities->append($city);
        return $this;
    }

    public function getCities() : ArrayObject
    {
        if ($this->cities == null) {
            $this->cities = new ArrayObject();
        }

        return $this->cities;
    }
}

无论如何...让我们用php自己的反射类解决您的问题。要获取声明类的属性,只需在city类中实现以下功能即可。

class City extends Country
{
    public $populationCity;

    public function getData() : array
    {
        $data = [];
        $reflection = new ReflectionClass($this);
        $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);

        foreach ($properties as $property) {
            if ($property->getDeclaringClass() == $reflection) {
                $data[$property->getName()] = $property->getValue($this);
            }
        }

        return $data;
    }
}

使用此方法,您只能获得City类的属性。让我们尝试一下...

$city = new City();
$city->populationCity = 10000;

var_dump($city->getData());

希望这会有所帮助。

答案 1 :(得分:0)

您可以使用Reflection来实现。

  

Reflection API,增加了对类进行反向工程的功能,   接口,功能,方法和扩展。此外,   反射API提供了检索函数文档注释的方法,   类和方法。

这将允许您枚举属性,并查看是否在类本身或其继承链中定义了任何给定的属性。

foreach ($cities as $city) {
    /* You can move this logic out of the loop and cache the properties 
       if your array contains only elements of the same type */
    $reflector = new ReflectionClass($city);
    $class = $reflector->getName(); // Get the name of the current class

    $ownProperties = array_map(function ($e) { return $e->name; },  // Return only the name of 
    // the property
        array_filter($reflector->getProperties(), // Return properties defined in 
        // the same class only, regardless the visibility, since protected properties can
        // either be declared or inherited
             // Check if declaring class is the same as this type
            function($e) use ($class) { return $class === $e->class; } ));
      /* **** */
    foreach ($ownProperties as $property) {
        echo $property . ': ' . $city->$property . '<br>';
    }
} 

Demo