简体   繁体   中英

How to access child class variables from parent class

I have the following case with class inheritance:

class Entity
{
  public $db; //connection

  ...
}

and classes Customer and Product extending Entity class:

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

As one can see here, each child class has the same function populate($row) which gets database row fetched from child class and populates corresponding class' variables; this function automatically fills variables: $this->cname=$row['cname'], $this->cdesc=$row['cdesc'] etc. (look at my other post here ).

Now I'd like to pull this function from children to parent class Entity and inherit it by all child classes but there's a problem. This function with $this->$key=$val dynamically fills (tries to fill) parent class variables and I'd like to fill child class variables. How to define that this function fills child class variables? (I'd like to have here something like child::$key=$val but child:: does not exist).

If you're trying to access specific data about one Product from another Product simply by the relation, then you can't do it.

If you're wanting to access child data from the parent, then I'd recommend creating an Interface that defines standardised ways to get the data you want:

interface EntityInterface
{
    public function getName();
    public function getDescription();
}

Then your Product simply defines the methods...

class Product extends Entity implements EntityInterface
{
    public $pname;

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

And your top-level Entity class uses those accessors:

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

Perhaps i am missing something but you can make the function protected then access it in child classes:

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

This is what Abstract classes are for. You define what you want in your parent class and then your children implement it. More or less, this is what Joe described, just rolled into a convenient class

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM