2016-03-07 61 views
0

我有以下类。我想要的是在主类(class1)中定义一个变量,通过构造()变量,然后从其他类中调用那些扩展了class1的变量。OOP:从class2中获取构造定义的class1的变量(扩展class1)

Class1的

<?php 

class Class1 { 

    protected $var1; 

    public function __construct($var1 = '') { 

     if (!empty($var1)) $this->var1 = $var1; 

    } 

    public function get_var() { 

     return $this->var1; 

    } 

} 

Class2中

<?php 
class Class2 extends Class1 {} 

指数

<?php 
require 'class1.php'; 

$class1 = new Class1('test'); 
echo 'Class1: ' . $class1->get_var(); 

require 'class2.php'; 

$class2 = new Class2(); 
echo '<br>Class2: ' . $class2->get_var(); 

这里的结果是,第一个Echo显示正确的值(测试),但第二个没有,只是一个空字符串。

那么,有没有一种方法可以做到这一点,而无需每次构造变量时都定义?

+0

即使您扩展了Class1,Class2也有自己的构造函数。您需要实现Class2的构造函数,并通过':: parent()' – hasumedic

+1

@hasumedic调用Class1的构造函数,这是我第一次阅读后才想到的,但这里的“问题”仅仅是$ class1和$ class2是两个不同的对象实例。没有办法,$ class2将具有相同的$ var1变量内容作为$ class1 ... – Zimmi

+0

确实。一个类的两个不同实例不会共享相同的属性,除非它们实际上是用相同的属性实例化的。因此,在一天结束时,OP将需要在Class2中实现一个构造函数,该构造函数调用Class1的构造函数并使用相同的值对其进行实例化。 – hasumedic

回答

1

你能做到这一点的想法与static所以你可以这样做:

<?php 
class Class1 { 

     protected static $var1; 

     public function __construct($var1 = '') { 

      if (!empty($var1)) self::$var1 = $var1; 

     } 

     public function get_var() { 

      return self::$var1; 

     } 

    } 

    class Class2 extends Class1 {} 

$class1 = new Class1('test'); 
echo 'Class1: ' . $class1->get_var(); 


$class2 = new Class2(); 
echo '<br>Class2: ' . $class2->get_var(); 

?> 
+1

完全不同意你的解决方案。您正在使用静态变量来绕过范围问题。静态变量不适用于这种目的。我想给用户一个这样的答案,(很明显)学习OOP的基础知识将导致他在将来处理更复杂的问题时会遇到很多问题。 –

+1

@AndrewReborn对不起,你一般说话这个答案中的具体问题是什么,你直到现在还没有引导我 –

+0

@GoudaElalfy在大多数情况下,使用静态变量是错误的原因很多。对于OOP原则,数据必须封装在对象内部。用你的答案,你实际上是使用静态变量来绕过状态变量$ var1的作用域(并因此封装)。 –

-1

请仔细检查您的代码:Class2扩展了超类Class1。 Class1在其自己的构造函数中具有$ var1参数,该参数被分配给状态变量$ var1(将访问权限设置为protected)。

当调用子类(在你的情况下是Class2)时,没有任何东西传递给它自己的构造函数。另外,你没有在你的Class2代码中定义任何构造函数。你可以这样做:

class Class2 extends Class1 { 
    public function __construct($var1 = '') { 
     parent::__construct($var1); 
    } 
} 

这里发生了什么?你实际上覆盖了__construct方法。如果不使用父:: _构造调用超类的方法__construct,则只会执行Class2定义的方法。 parent :: {method_name}将使您能够在重写的方法内调用Class1构造方法(在这种情况下,您正在扩展__construct功能)。

当你要实例Class2时,传递一个字符串给构造函数,状态变量$ var1将被赋值。请记住扩展一个你继承了它的所有属性和方法的类。

+1

在PHP中,“Parent构造函数不会隐式调用**如果**子类定义了构造函数“([doc](http://php.net/manual/en/language.oop5.decon.php))。因此,如果子类没有定义构造函数,则会调用父**的构造函数。这意味着在这个非常特殊的情况下,不需要Class2中的构造函数。只需调用'$ class2 = new Class2('value');' – Zimmi

+0

我从来没有对构造函数的隐式/显式调用说过什么。如果你仔细阅读我的答案,我会说“你实际上覆盖了__construct方法”。当我说没有任何东西传递给class2的构造函数时,就是在他的代码中,这是声明:$ class2 = new Class2();实际上没有任何事情可以通过。我只是想给他一个更复杂的概述,说明他对这种方法的适用情况和机会。 –

-1

这个例子正常工作。

如果目的是使用class1实例化并且class2具有这些属性。在情况下,也需要class2的新属性,一个新的Class1可以用不同的属性保留如下:

<?php 

class Class1 { 

    protected static $var1; 

    public function __construct($var1 = '') { 

     if (!empty($var1)) self::$var1 = $var1; 

    } 

    public function get_var() { 

     return self::$var1; 

    } 

} 

    class Class2 extends Class1 {} 

    $class1 = new Class1('test'); 
    echo 'Class1: ' . $class1->get_var() . "\n"; 

    $class2 = new Class2(); 
    echo 'Class2: ' . $class2->get_var() . "\n"; 

    $class1 = new Class1('prod'); 
    echo 'Class1: ' . $class1->get_var() . "\n"; 

    $class2 = new Class2(); 
    echo 'Class2: ' . $class2->get_var() . "\n"; 

?> 

输出:

的Class1:测试

等级2:测试

的Class1:督促

等级2:督促

+0

这与给定的答案基本相同由@GoudaElalfy,但与输出......并在25分钟之间..似乎合法。 (顺便说一下,不是我的downvote)。编辑:你甚至没有说你改变了什么,为什么。 – FirstOne

+0

请检查更新的回复,我只是测试了代码并为类继承中的静态变量提供证明。 – Kruser

相关问题