Доступ дочернего класса PHP к родительской переменной - PullRequest
11 голосов
/ 07 мая 2009

Я получил этот класс:

Class Username {
protected $id;
protected $username;
protected $contact_information;

     private __construct($id) {
       $this->id = (int) $id; // Forces it to be a string
       $contact_information = new ContactInformation($this->id);
     }
}

Class ContactInformation extends Username {
    protected $mobile;
    protected $email;
    protected $nextel_id;
    .....
}

Моя проблема: я хочу получить доступ к $ id и $ username (и множеству других переменных) в ContactInformation, но parent :: или $ this-> НЕ работает, похоже, что каждый раз, когда я это делаю, новая ContactInformation .. ..) PHP создает «новое имя пользователя». Есть ли шанс получить доступ к значениям CURRENT из имени пользователя?

Спасибо

Ответы [ 5 ]

12 голосов
/ 07 мая 2009

Почему конструктор имени пользователя закрыт? Если вы хотите сделать невозможным создание имени пользователя, сделайте класс имени пользователя абстрактным. Кроме того, НЕ делайте новую контактную информацию из родительского класса. Вот еще один способ выразить это:

abstract class Username {
   protected $id;
   protected $username;

   public __construct($id) {
      $this->id = (int) $id; // Forces it to be a string
   }
}

class ContactInformation extends Username {
    protected $mobile;
    protected $email;
    protected $nextel_id;
    public __construct($id, $mobile, $email, $nextel_id) {
       parent::__construct($id)
       $this->mobile = $mobile;
       ....
    }
}

Теперь вместо непосредственного создания имени пользователя (что теперь невозможно) вместо этого вы создаете ContactInformation. Затем ContactInformation вызывает конструктор Username в своем собственном конструкторе.

8 голосов
/ 07 мая 2009

parent :: method используется только для доступа к родительским методам, которые вы переопределили в своем подклассе, или к статическим переменным, таким как:

class Base
{
    protected static $me;

    public function __construct ()
    {
        self::$me = 'the base';
    }

    public function who() {
        echo self::$me;
    }
}

class Child extends Base
{
    protected static $me;

    public function __construct ()
    {
        parent::__construct();
        self::$me = 'the child extends '.parent::$me;
    }

    // until PHP 5.3, will need to redeclare this
    public function who() {
        echo self::$me;
    }
}

$objA = new Base;
$objA->who(); // "the base"

$objB = new Child;
$objB->who(); // "the child extends the base"

Вы, вероятно, хотите правильный подкласс. Не создавайте подкласс в конструкторе базового класса, который переворачивает все виды лучших практик ООП вверх ногами (слабая связь и т. Д.), А также создает бесконечный цикл. (new ContactInformation () вызывает конструктор Username, который создает новую ContactInformation (), которая ...).

Если вы хотите подкласс, что-то вроде этого:

/**
 * Stores basic user information
 */
class User
{
    protected $id;
    protected $username;

    // You could make this protected if you only wanted
    // the subclasses to be instantiated
    public function __construct ( $id )
    {
        $this->id = (int)$id; // cast to INT, not string

        // probably find the username, right?
    }
}

/**
 * Access to a user's contact information
 */
class ContactInformation extends User
{
    protected $mobile;
    protected $email;
    protected $nextel;

    // We're overriding the constructor...
    public function __construct ( $id )
    {
        // ... so we need to call the parent's
        // constructor.
        parent::__construct($id);

        // fetch the additional contact information
    }
}

Или вы можете использовать делегата, но тогда методы ContactInformation не будут иметь прямого доступа к свойствам имени пользователя.

class Username
{
    protected $id;
    protected $contact_information;

    public function __construct($id)
    {
        $this->id = (int)$id;
        $this->contact_information = new ContactInformation($this->id);
    }
}

class ContactInformation // no inheritance here!
{
    protected $user_id;
    protected $mobile;

    public function __construct($id)
    {
        $this->user_id = (int)$id;
        // and so on
    }
}
2 голосов
/ 07 мая 2009

Во-первых, когда вы создаете ContactInformation, он также содержит все не частные свойства и методы Username. Вам не нужен отдельный Username экземпляр.

Class Username {
    protected $id;
    protected $username;

    protected __construct($id) {
        $this->id = (int) $id; // Forces it to be a string
    }
}

Class ContactInformation extends Username {
    protected $mobile;
    protected $email;
    protected $nextel_id;
    // Pretend that these are here because they're defined in my parent
    //protected $id;
    //protected $username;

    public __construct($id) {
        parent::__construct($id);
        echo $this->id; //Should echo 1
    }
}

Однако, поскольку все поля защищены, это не сработает:

$contact_information = new ContactInformation(1); // Works fine
echo $contact_information->id;
// Whoops, visibility error because id isn't public
1 голос
/ 07 мая 2009

Если я правильно вас понимаю, вы хотите получить доступ к свойствам объекта из объекта, содержащегося в этом объекте? Если это правильно, вот как это делается:

class A {

  // These are the properties you want to access from the child object
  public $property_a;
  public $property_b;
  public $property_c;

  // This is the child object variable
  public $child_object;

  public function __construct( ) {

    // Pass 'this' into the child so that the child has a reference back to the parent
    $this->child_object = new B($this);
  }
}

class B {

  // Holds a reference to the parent object
  protected $parent_object;

  public function __construct( $object ) {

    // Remember the reference to the parent object
    $this->parent_object = $object;
  }

  // Just a Demonstration Method
  public print_parent_property_a()
  {
    // Reach into the referred parent object, and get it's property
    print $this->parent_object->property_a;
  }
}

Так что, если вы должны были сделать:

$my_object = new A();
$my_object->property_a = 'test_value';
$my_object->child_object->print_parent_property_a();

Вы получите 'test_value'

Это немного отличается от вашего примера тем, что вам нужно, чтобы свойства родительского класса были общедоступными, чтобы ребенок мог к ним обращаться.

Это все работает, потому что в PHP объекты всегда передаются по ссылке, если вы не клонируете их явным образом.

0 голосов
/ 04 августа 2016
<?php

 abstract class employee
{ 
    //create member variable in parent class

    protected $name;
    protected $id;
    protected $mobile;  

    //constructor of parent class 
    public function __construct($n , $i , $m)
    {
        $this->name=$n;
        $this->id=$i;
        $this->mobile=$m;
    }
    //create method will return name
    public function ShowFullName()
    {

        return $this->name;
    }
//create method will return contact
    public function ShowContact()
    {

        return $this->mobile;
    }

}

class FulltimeEmployee extends employee
{

    private $days;
    private $salary;



        //create child constructor 
    public function __construct($n , $i , $mo , $d , $s)
    {
        $this->days=$d;
        $this->salary=$s;

        //calling parent constructor now we can use parent class member while calling child class constructor
        parent::__construct($n , $i , $mo);
    }

    public function calculate()
    {

        return $this->salary * $this->days;

    }
}

//providing data to child class constructor including parent class values
$child = new FulltimeEmployee("james",120,9033474118 , 2 , 200);
echo $child->calculate();
echo $child->ShowFullName();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...