PHP-класс доступа к родительским переменным

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

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- > НЕ работает, выглядит каждый раз, когда я делаю "new ContactInformation....) PHP создает" новое имя пользователя". Любая возможность получить доступ к значениям CURRENT из Username?

Спасибо

Ответ 1

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

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 в своем собственном конструкторе.

Ответ 2

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

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 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 не будут иметь прямого доступа к свойствам Username.

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

Ответ 3

Во-первых, при создании 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

Ответ 4

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

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 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 объекты всегда передаются по ссылке, если вы не просто клонируете их.

Ответ 5

<?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();