简体   繁体   English

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

[英]How can I create a child class which only inherits the methods but not the properties of the parent?

Suppose I have this code: 假设我有以下代码:

First I created the Parent 首先,我创建了父母

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

with some methods(which are not relevant for this question) 使用某些方法(与该问题无关)

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

Then I create the child 然后我创造一个孩子

 Class city extends Country 
{
public $populationcity;
} 

Then I create the objects (fot this example I only created one) 然后创建对象(此示例仅创建了一个)

$city1 = new city();

$city1->populationcity = 10000; 

and an array of the objects 和一组对象

$cities = [$city1];    

And finally I want to 'echo' only the child's properties (populationcity) 最后,我只想“回声”孩子的财产(人口密度)

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

Output : 输出
populationcity:10000 人口城市:10000
country: 国家:
populationcountry: 人口国家:
language: 语言:

I want to keep the methods of the parent, but not the properties of the parent. 我想保留父级的方法,但不保留父级的属性。 How can I achieve that? 我该如何实现?


David in the comments told me to set the properties to Private. David在评论中告诉我将属性设置为Private。 I did so, and it worked fine but when I created a Country object , it prints the parent's property in the child class. 我这样做了,但效果很好,但是当我创建Country对象时,它将在子类中打印父级的属性。

This is the code, which gives me this output when the parent properties are Public. 这是代码,当父属性为Public时,将为我提供此输出。

populationcity: 10000 人口城市:10000
country: 国家:
populationcountry: 人口国家:
language: 语言:
country: England 国家:英格兰
populationcountry: 30000 人口国家:30000
language: English 英语语言

It should print: 它应该打印:

populationcity: 10000 人口城市:10000
country: England 国家:英格兰
populationcountry: 30000 人口国家:30000
language: English 英语语言

When I set them to Private I get this: 当我将它们设置为私人时,我得到以下信息:

Fatal error: Uncaught Error: Cannot access private property Country::$language in C:\\xampp\\htdocs\\ejercicios.php:141 Stack trace: #0 {main} thrown in C:\\xampp\\htdocs\\ejercicios.php on line 141 致命错误:未被捕获的错误:无法访问私有属性国家:: $ C:\\ xampp \\ htdocs \\ ejercicios.php:141中的语言堆栈跟踪:#0 {main}抛出C:\\ xampp \\ htdocs \\ ejercicios.php 141

And when I set them to Protected I get this: 当我将它们设置为“受保护”时,我得到以下信息:

Fatal error: Uncaught Error: Cannot access protected property Country::$language in C:\\xampp\\htdocs\\ejercicios.php:141 Stack trace: #0 {main} thrown in C:\\xampp\\htdocs\\ejercicios.php on line 141 致命错误:未被捕获的错误:无法访问受保护的属性国家:: $ C:\\ xampp \\ htdocs \\ ejercicios.php:141中的语言堆栈跟踪:#0 {main}被抛出到C:\\ xampp \\ htdocs \\ ejercicios.php中141

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>';

}

} }

Looks like a bad design pattern. 看起来像一个糟糕的设计模式。 For me a country can contain several different cities. 对我来说,一个国家可以包含几个不同的城市。 Therefore a city is not a country. 因此,城市不是国家。 Shouldn 't your country entity class look like this? 您所在的国家/地区实体类不应该是这样吗?

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;
    }
}

Anyway ... let us solve your issue with php's own reflection classes. 无论如何...让我们用php自己的反射类解决您的问题。 To get the properties of the declaring class only just implement the following function in the city class. 要获取声明类的属性,只需在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;
    }
}

With this you can get the properties of the City class only. 使用此方法,您只能获得City类的属性。 Let us have a try ... 让我们尝试一下...

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

var_dump($city->getData());

Hope this helps. 希望这可以帮助。

You can use Reflection to achieve this. 您可以使用反射来实现。

Reflection API that adds the ability to reverse-engineer classes, interfaces, functions, methods and extensions. 反射API,增加了对类,接口,函数,方法和扩展进行反向工程的能力。 Additionally, the reflection API offers ways to retrieve doc comments for functions, classes and methods. 另外,反射API提供了检索函数,类和方法的文档注释的方法。

This will allow you to enumerate the properties and see if any given one is defined in the class itself or along its inheritance chain. 这将允许您枚举属性,并查看是否在类本身或其继承链中定义了任何给定的属性。

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 演示版

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用父类方法填充的子类属性 - Child class properties populated with parent class methods 如何创建一个动态扩展类的工厂,以便其类型发生变化,但它继承父方法? - How do you create a factory that dynamically extends a class so its type changes but it inherits parent methods? 如何将子类的属性添加到父类的方法中 - How can I can get a child class's attributes into the parent class's methods php中哪个文件继承了代码(父-子) - Which file in php inherits code (parent - child) 在父类中使用$ this仅显示子类中的父类属性 - show only parent class properties in child class using $this in parent class 如何通过父组件到 livewire / laravel 中的子组件创建动态公共属性和数据? - How can I create dynamic public properties and data via a parent component to a child component in livewire / laravel? 我可以从父类中创建子类吗? - Can I create a child class out of a parent class? OO PHP-子类不继承父方法和属性 - OO PHP - child class not inheriting parent methods and properties 我可以在Laravel 5.2中创建一个继承自User的新类吗? - Can I create a new class that inherits from User in Laravel 5.2? 从父类扩展的子PHP类如何将值添加到父类数组属性上? - How can a child PHP class which extends from a parent class, add values on to the parent classes array property?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM