简体   繁体   English

PHP-OOP类扩展

[英]PHP - OOP class extend

Been searching all around but still cannot find a solution for this problem. 一直在搜索,但是仍然找不到解决此问题的方法。 My problem is that i got these snips of code(Examples): 我的问题是我得到了以下代码片段(示例):

Core file 核心文件

class Core {
    public $DB = null;
    public $Handler = null;

    function run() {
        $this->DB = "somedatabase";

        include_once('handler.php');
        $this->Handler = new Handler;

        $this->Handler->run();
    }
}

This is the helper.php example 这是helper.php示例

class Handler extends Core {
    function run() {
        echo "<pre>"; print_r($this); echo "</pre>"; die();
    }
}

Even tho i defined the DB variable before i include the helper then it is still empty inside the helper class. 甚至在包含帮助程序之前就定义了DB变量,然后它在帮助程序类中仍然为空。 It's defined yes but it's empty. 定义为是,但为空。 Which means it properly doesn't share the same memory as the Core class. 这意味着它正确地不共享与Core类相同的内存。

Keep in mind that the Core class it self is instanced too. 请记住,它本身的Core类也是实例化的。

- --

Thanks for all suggestions 感谢所有建议

Edit 编辑

PhpMyCoder got it right. PhpMyCoder正确了。 Thank you for the detailed and well written reply. 感谢您的详细答复。 For over 2 years i been seeing PHP scopes as being the same or sorta the same as JavaScript's scope. 两年多来,我一直认为PHP范围与JavaScript范围相同或大致相同。 Now i realize that if i extend my "Core" class i get all the methods and properties within it. 现在我意识到,如果扩展我的“ Core”类,我将获得其中的所有方法和属性。 But the values is private to my class and my class alone. 但是这些价值观对于我的班级和我的班级都是私有的。

This is great. 这很棒。 Finally i got it. 终于我明白了。

From what I gather here you are talking about public instance variables. 从我这里收集的内容来看,您正在谈论公共实例变量。 They are performing as OOP would require. 它们的性能达到了OOP的要求。 Each time you instantiate a class with 每次您实例化一个类时,

$core = new Core();  // or
$handler = new Handler();

Each of them gets a fresh space in memory to store their instance variables. 它们每个都在内存中获得了一个新空间来存储其实例变量。 Instance variables are unique to each instance of a class, as the name would suggest. 顾名思义,实例变量对于类的每个实例都是唯一的。 So, two separate instances of Core and Handler do not share instance variables. 因此,Core和Handler的两个单独实例不共享实例变量。 However since Handler extends Core, two instances of Core are created. 但是,由于Handler扩展了Core,因此创建了两个Core实例。 One instance is the one that I created on the first line. 一个实例是我在第一行中创建的。 The other is created so that Handler can extend it on the second line. 创建另一个,以便Handler可以在第二行扩展它。 These two instances of Core are not the same object. 这两个Core实例不是同一对象。 To have the same values for Core across all core objects you will need to use static (class) variables. 要使所有核心对象的Core值相同,您将需要使用静态(类)变量。

class Core {
    public static $hello = 'World';
}

var_dump(Core::$hello); //string('Word')

In my example, $hello will always be available to everyone by accessing it with the scope resolution operator, :: . 在我的示例中, $hello始终可以通过使用范围解析运算符::进行访问而提供给所有人。 So Handler could access it with either Core::$hello or parent::$hello . 因此, Handler可以使用Core::$helloparent::$hello来访问它。 If you wanted to only expose this static variable to Core and its subclasses, then you would need to make it protected and access it from within Core with self::$hello and from its subclasses with parent::$hello . 如果您只想将此静态变量公开给Core及其子类,则需要对其进行protected并使用self::$helloCore进行访问,并使用parent::$hello从其子类对其进行访问。

class Core {
    protected static $hello = 'World';

    public function sayHello() {
        echo 'Hello '.self::$hello;  //from within Core, access with `self`
    }
}

class Handler extends Core {
    public function myParentSays() {
        echo 'My parent says: Hello '.parent::$hello;
    }
}

$core = new Core();
$core->sayHello(); // 'Hello World'

$handler = new Handler();
$handler->myParentSays(); // 'My parent says: Hello World'

Check the PHP docs for more on the static keyword and the scope resolution operator . 有关静态关键字范围解析运算符的更多信息,请查看PHP文档。


EDIT 编辑
I believe your confusion lies in a misunderstanding of how inheritance works in OOP so let me give you a little real-world-ish example. 我相信您的困惑在于对继承在OOP中的工作方式的误解,所以让我给您举一个现实世界的例子。 Let's say you create a class for employees called Employee . 假设您为员工创建了一个名为Employee的类。 This class has a public instance variable (that is, one that can be accessed with -> ) for the name of the person. 该类具有一个公共实例变量(即,可以使用->访问的变量)作为人的名字。 In PHP this would be: 在PHP中,这将是:

class Employee {
    public $name;

    public __construct($name) {
        $this->name = $name;
    }
}     

Now let's create a new employee: 现在让我们创建一个新员工:

$tim = new Employee('Tim');

Let's say that we need a new class, Intern , that should subclass Employee . 假设我们需要一个新类Intern ,它应该将Employee子类化。 That should be easy enough: 那应该很容易:

class Intern extends Employee {
    public function makeCoffee(Employee $receiver) {}
}

If we create a new intern now, should his name be Time just because we have already created another employee named Tim? 如果我们现在创建一个新的实习生,他的名字应该只是因为我们已经创建了另一个名为Tim的员工吗? No. That doesn't make sense. 不,那没有道理。

$intern = new Intern();
var_dump($intern->name); //string(0) ""

Now say that setting the name was some complicated and arduous process and we'd rather not have to code it again. 现在说设置名称是一个复杂而艰巨的过程,我们宁愿不必再次对其进行编码。 With a little modification to our Intern class we can leave the name setting to its superclass, Employee . 在对Intern类进行一些修改后,我们可以将名称设置保留为其超类Employee

class Intern {
    public function __construct($name) {
        parent::__construct($name);
    }

    public function makeCoffee(Employee $receiver) {}
}

Now we can create a new intern and set his or her name. 现在,我们可以创建一个新的实习生并设置他或她的名字。 Notice how the other Employee keeps his name. 注意另一位雇员如何保留其姓名。

$intern = new Intern('Something Forgettable');
var_dump($intern->name); // string(21) "Something Forgettable"
var_dump($employee->name); // string(3) "Tim"

Now why is this? 现在为什么呢? In OOP, a subclass/superclass is an "is a" relationship. 在OOP中,子类/超类是“是”关系。 The Intern "is an" Employee . Intern “是” Employee The Intern has all the same properties and methods as an Employee but because each Intern and Employee are distinct they have their own values for these properties. Intern具有与Employee相同的所有属性和方法,但是由于每个InternEmployee是不同的,因此它们对于这些属性具有自己的值。

With this in mind, I suggest you rethink your strategy for your classes. 考虑到这一点,我建议您重新考虑您的课堂策略。 Does it really make sense that Handler is a Core ? HandlerCore真的有意义吗? Does it make sense that MainController is a Handler ? MainControllerHandler是否有意义?

Classes don't share memory unless you pass a reference to them. 除非您传递对类的引用,否则它们不会共享内存。 When you make an instance of a class (an object), it is unique. 创建类(对象)的实例时,它是唯一的。 You could have: 你可以有:

$a = new Core();
$b = new Core();
$a->var1 = 'foo';
$b->var1 = 'bar';
echo $a->var1; // 'foo'
echo $b->var1; // 'bar'

The same holds for extending a class. 扩展类也是如此。 It doesn't explicitly share the values of the fields, it just shares their existence/visibility. 它没有明确共享字段的值,只是共享它们的存在/可见性。

To share the value, you would do something more like this: 为了分享价值,您可以做以下事情:

$a = new Core();
$b = new Core();
$c = 'foo';
$a->var1 = &$c;
$b->var1 = &$c;
echo $a->var1; // 'foo'
$b->var1 = 'bar';
echo $a->var1; // 'bar'
$c = 'baz';
echo $a->var1; // 'baz'

Variables are only set on objects (class instances). 变量仅在对象(类实例)上设置。 Don't confuse classes with objects. 不要将类与对象混淆。

If you want to have variables bound to classes, use the static keyword: 如果要将变量绑定到类,请使用static关键字:

class Core {
  public static $static = 'abc';
  public $instance = 'xyz';
}
Core::$static = 'x';
$core = new Core();
$core->instance = 'a';

In PHP, classes are extended, not objects. 在PHP中,类是扩展的,而不是对象的。 This is class: 这是课程:

class SomeClass{
   // ...
}

And this is object: 这是对象:

$object = new SomeClass();

So, when your are extending some class, all its protected/public properties are become available to child class . 因此,当您扩展某个类时,其所有受保护/公共属性将对子可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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