php PHP子类访问父变量问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/831555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP Child class accessing Parent variable problem
提问by
I got this class:
我上了这门课:
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;
.....
}
My problem is: I want to access the $id and $username (and lots of other variables) on ContactInformation, but parent:: or $this-> does NOT work, looks like everytime i do "new ContactInformation....) PHP creates a "new Username". Any chance to access the CURRENT values from Username?
我的问题是:我想访问 ContactInformation 上的 $id 和 $username(以及许多其他变量),但是 parent:: 或 $this-> 不起作用,看起来每次我执行“new ContactInformation....) PHP 创建一个“新用户名”。有机会从用户名访问 CURRENT 值吗?
Thanks
谢谢
回答by PatrikAkerstrand
Why is the Username constructor private? If you mean to make it impossible to create a Username, make the Username class abstract. Also, do NOT make a new contact information from the parent class. Here's another way to put it:
为什么用户名构造函数是私有的?如果您想让创建用户名变得不可能,请将 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;
....
}
}
Now, instead of instantiating the Username directly (which is now impossible), you instead create a ContactInformation. ContactInformation then calls the Username constructor in its own constructor.
现在,不是直接实例化用户名(现在是不可能的),而是创建一个 ContactInformation。ContactInformation 然后在它自己的构造函数中调用 Username 构造函数。
回答by James Socol
The parent:: method is only used to access parent methods that you have overridden in your subclass, or static variables like:
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"
You probably want a proper subclass. Don't create a subclass in the constructor of the base class, that turns all sorts of OOP best-practices upside down (loose coupling, etc) while also creating an infinite loop. (new ContactInformation() calls the Username constructor which creates a new ContactInformation() which...).
你可能想要一个合适的子类。不要在基类的构造函数中创建子类,这会颠倒各种 OOP 最佳实践(松散耦合等),同时还会创建无限循环。(new ContactInformation() 调用 Username 构造函数,它创建一个新的 ContactInformation() ......)。
If you want a subclass, something like this:
如果你想要一个子类,像这样:
/**
* 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
}
}
Or you could use a delegate, but then the ContactInformation methods wouldn't have direct access to the Username properties.
或者您可以使用委托,但是 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
}
}
回答by Powerlord
First, when you create a ContactInformation, it is also contains all the non-private properties and methods of Username. You do not need a separate Usernameinstance.
首先,当您创建 时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
}
}
However, since all the fields are protected, this isn't going to work:
但是,由于所有字段都受到保护,因此这行不通:
$contact_information = new ContactInformation(1); // Works fine
echo $contact_information->id;
// Whoops, visibility error because id isn't public
回答by Jonathan Hanson
If I understand you correctly, you want to access properties of an object from an object contained in that object? If this is correct, here's how its done:
如果我理解正确,您想从该对象中包含的对象访问该对象的属性吗?如果这是正确的,这是它的完成方式:
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;
}
}
So if you were to do:
所以如果你要这样做:
$my_object = new A();
$my_object->property_a = 'test_value';
$my_object->child_object->print_parent_property_a();
You'd get 'test_value'
你会得到'test_value'
It's slightly different from your example, in that you'll need the parent class properties to be public so that the child can access them.
它与您的示例略有不同,因为您需要将父类属性设为公开,以便子类可以访问它们。
This all works because in PHP, objects are always passed by reference unless you explicity clone them.
这一切都有效,因为在 PHP 中,对象总是通过引用传递,除非您明确克隆它们。
回答by Zoyeb Shaikh
<?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();

