关于php:如何从父类访问子类变量

How to access child class variables from parent class

对于类继承,我有以下情况:

1
2
3
4
5
6
class Entity
{
  public $db; //connection

  ...
}

和类客户和产品扩展实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Customer extends Entity
{
   public $cname;
   public $cdesc;

   private function populate($row)
   {
     foreach($row as $key=>$val) $this->$key=$val;
   }

   public function fetch()
   {
     $sql="SELECT cname,cdesc FROM customers";
     $rst=$this->db->query($sql);
     $row=$rst->fetch_assoc();
     $this->populate($row);
   }
}

class Product extends Entity
{
   public $pname;
   public $pdesc;

   private function populate($row)
   {
     foreach($row as $key=>$val) $this->$key=$val;
   }

   public function fetch()
   {
     $sql="SELECT pname,pdesc FROM products";
     $rst=$this->db->query($sql);
     $row=$rst->fetch_assoc();
     $this->populate($row);
   }
}

正如我们在这里看到的,每个子类都有相同的函数popute($row),它从子类中获取数据库行并填充相应的类变量;这个函数自动填充变量:$this->cname=$row['cname'],$this->cdesc=$row['cdesc']等(请看我的其他文章)。

现在,我想将这个函数从子类拉到父类实体,并由所有子类继承它,但有一个问题。函数$this->key=$val动态填充(尝试填充)父类变量,我想填充子类变量。如何定义该函数填充子类变量?(我希望这里有类似child::$key=$val的内容,但是child::不存在)。


也许我遗漏了一些东西,但是您可以使函数受保护,然后在子类中访问它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Entity
{
    protected  $db; //connection

    protected  function populate($row)
    {
        foreach($row as $key=>$val) $this->$key=$val;
    }
}


class Customer extends Entity
{
    public $cname;
    public $cdesc;

    public function fetch()
    {
        $sql="SELECT cname,cdesc FROM customers";
        $rst=$this->db->query($sql);
        $row=$rst->fetch_assoc();
        $this->populate($row);
    }
}

class Product extends Entity
{
    public $pname;
    public $pdesc;

    public function fetch()
    {
        $sql="SELECT pname,pdesc FROM products";
        $rst=$this->db->query($sql);
        $row=$rst->fetch_assoc();
        $this->populate($row);
    }
}


如果您试图通过关系从另一个产品访问关于一个产品的特定数据,那么您就不能这样做。

如果您想从父级访问子级数据,那么我建议您创建一个接口,定义获取所需数据的标准化方法:

1
2
3
4
5
interface EntityInterface
{
    public function getName();
    public function getDescription();
}

然后你的产品简单地定义了方法…

1
2
3
4
5
6
7
8
class Product extends Entity implements EntityInterface
{
    public $pname;

    public function getName() {
        return $this->pName;
    }
}

顶级实体类使用这些访问器:

1
2
3
4
5
6
class Entity
{
    public function printName() {
        echo $this->getName();
    }
}


这就是抽象类的用途。在父类中定义所需内容,然后由子类实现。或多或少,这就是乔所描述的,刚刚进入一个方便的班级。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
abstract class Entity
{
    // Note that we're defining this here and not in the child
    // so we're guaranteed this is set
    /* @var string */
    public $pName;

    public function printName() {
        echo $this->getName();
    }

    abstract public function getName($name);
}

class Product extends Entity
{
    //Note that, just like an interface, this has to implement it just like the parent
    public function getName($name) {
        return $this->pName;
    }
}