【问题标题】:PHP Multiple Classes Extending OnePHP 多类扩展一
【发布时间】:2013-10-15 21:56:05
【问题描述】:

我有 4 个课程: Main SQL Template Member .我想要SQL TemplateMember 扩展 Main 类。 但同时,我希望不能同时调用所有类,也不需要它们。

所以,在我的index.phpfile 中,我会调用MainTemplate
在我的register.php 页面中,我会调用MainTemplateSQLMember
在我的submit.php 页面中,我会调用MainSQLMember

我有这样的课程:

------ Main Class ------

<?php

public $db;

class Main {

    public function __construct(){
    }
    public function One(){
        // here I would call Two, Three, and Four if available
    }
}


-----SQL Class ------

<?php
class SQL extends Main {
    public function __construct(){
        parent::__construct();
        $this->db = new mysqli(....);
    }
    public function Two(){
        $this->db->query(.....);
        // Fetch query code
        echo $result;
    }
}


-----Template Class ------

<?php
class SQL extends Main {
    public function __construct(){
        parent::__construct();
        $this->db = new mysqli(....);
    }
    public function Three(){
        $this->db->query(.....);
        // Fetch query code
        echo $result;
    }
}


Member 类将与其他类相同,并具有四个功能。

所以,我就是这样做的,但我无法从子类调用函数,只能从主类调用。

你能告诉我一个更好的方法吗? 提前谢谢你。

【问题讨论】:

标签: php class extend


【解决方案1】:

如果您真的需要 Main 类中的 twothreefour 方法而不实现它们,则必须将其抽象化并强制子类实现 all 其中(这是绝对可以接受的,也是做这种事情的好方法)。

<?php

abstract class Main {

  function fn1() {
    $this->fn2();
    $this->fn3();
  }

  abstract function fn2();

  abstract function fn3();

}

class Child extends Main {

  function fn2() {
    return "foo";
  }

  function fn3() {
    return "bar";
  }

}

?>

另一种选择是检查方法是否存在(不好/破解/请参阅下面的评论)。

<?php

class Main {

  function fn1() {
    if (method_exists($this, "fn2")) {
      $this->fn2();
    }
    if (method_exists($this, "fn3")) {
      $this->fn3();
    }
  }

  function fnDontRepeatYourself() {
    foreach (range(2,3) as $fn) {
      if (method_exists($this, $fn)) {
        $this->{$fn}();
      }
    }
  }

}

?>

第二种方法的问题是孩子们实际上并不知道他们必须实现这些方法,这是有问题的。

继承应该从一般到特殊,你不应该在你的类中echo 任何东西,而是return。我现在可以告诉你很多关于该做什么和不做什么的事情,但我认为最好先了解更多有关面向对象的理论,然后再继续。 :)

【讨论】:

  • 那么,我应该在 Main 中拥有所有类中需要的函数,而在其他类中拥有其他函数,对吗? - 我实际上并没有回显,我返回它,并且只在最终的 PHP 文件中回显一次。我只是在示例中这样做了。感谢您的帮助
  • 我扩展了我的答案以包含一个示例子类。很好,请始终尝试在您的课程中进行没有副作用的编程(例如echohead())。你需要某种入口点来回显你的输出当然是完全可以和必要的。我希望我的例子是对你的帮助,否则继续问。 ;)
  • 我在声明类抽象时遇到问题。您可以在 Skype 上添加我并尝试通过 TeamViewer 查看问题吗?如果是这样,我的 Skype 是 xG.WilliamSantos
  • 只要确保类是抽象的&lt;?php abstract class Name {} ?&gt; 和你不想实现的方法abstract function name(); 这就是你所要做的。请阅读手册以充分理解它,我想你有时间这样做,以后你会更好地理解一切:php.net/manual/en/language.oop5.abstract.php
  • 它只是说“致命错误:无法实例化抽象类 Main”。我会阅读文档,谢谢。
【解决方案2】:

在您的 Main 类上实现 Two()、Three() 和 Four()。他们不必做任何事情。然后,您可以从 Main 中调用它们 - 它们将执行您调用 One() 的类的覆盖函数中实现的操作。

【讨论】:

  • 您能否具体说明如何实现它们(举个例子)? - 我是新来的课程。
  • 在您的主类中,定义名为二、三和四的方法,但没有实现。例如。公共函数 MethodName() {}
  • 好的,但是我需要从它们被覆盖的类中调用它们,对吧?我希望当我从 Main 类调用函数 One 时调用它们。
  • 在您的 One 函数中调用函数。例如。 $this->Two(); $this->Three(); $this->Four();
【解决方案3】:

不要让这些类继承主类。 SQL、模板和成员没有太多共同点。因此,它们不应该扩展公共类Main,它们应该是独立的。普通的大师班会让事情变得更复杂。

存在不止一个类需要访问数据库的情况。这是组合发挥作用的时候。 Member 类应该能够读取和写入数据库 - 您应该创建一个 SQL 对象并将其传递给 Member 对象。如果模板也存储在数据库中,这同样适用于 Template 类。

我的问题是:我无法深入了解好的面向对象编程的全部内容,因为这会填满书籍,并且不适合 Stackoverflow 上的问答格式。所以我只能建议你阅读更多关于这个主题的东西,避免God object pattern

【讨论】:

  • 感谢您的回答。如何“创建SQL 对象并将其传递给Member 对象”?
  • $sql = new SQL; $member = new Member($sql); - sql 对象将存储在内部,然后可以由需要数据库的任何 Member 方法使用。
猜你喜欢
  • 1970-01-01
  • 2011-06-11
  • 2013-06-14
  • 2015-06-19
  • 2012-06-27
  • 2012-07-31
  • 2013-02-06
  • 2017-01-09
  • 2016-05-09
相关资源
最近更新 更多