1

想象一下,两个类共享几乎完全相同的方法和属性,都扩展了父类,但差异很小。

class fields { 
 public function __construct() {
  global $id;
  $this->id = $id++;
 }
}

class input extends fields {
 public function __construct() {
  parent::__construct();
 }
 public function draw() {
  echo '<input>';
 }
}

class textarea extends fields {
 public function __construct() {
  parent::__construct();
 }
 public function draw() {
  echo '<textarea>';
 }
}

我认为以这种伪代码方式重写 textarea 类会更有效:

class textarea extends fields {
 public function __construct() {
  $this = new input(); // <<------ 
 }
 public function draw() {
  echo '<textarea>';
 }
}

基本上,我不确定如何最好地做到这一点,以便该类的行为类似于第一个示例中的类。

本质上,我想使用 OOP 执行以下操作,但能够像上面第一个示例中那样使用对象(能够调用可能重载的方法,具有不同的属性等):

function a() {echo '123';}
function b() {a();}

刚刚把整个类都抄下来了,修改了几行,感觉很浪费。

最终答案 感谢这些人,这是与示例调用的组合答案:

abstract class fields { 
 private static $masterid = 0;
 public function __construct() {
  $this->id = self::$masterid++;
 }
}

class input extends fields {
 public $data;
 public function __construct($new = '') {
  parent::__construct();
  if ($new) $this->data = $new;
  else $this->data = 'Hello';
 }
 public function draw() {
  echo '<input>'.$this->export().'</input>';
 }
 public function export() {
  return 'ID '.$this->id.' = '.$this->data;
 }
}

class textarea extends input {
 public function __construct($new = '') {
  parent::__construct($new);
 }
 public function draw() {
  echo '<textarea>'.$this->export().'</textarea>';
 }
}

$a = new textarea();
$a->draw();
$a = new textarea('World');
$a->draw();
$a = new input('!');
$a->draw();

//Outputs:
// <textarea>ID 0 = Hello</textarea>
// <textarea>ID 1 = World</textarea>
// <input>ID 2 = !</input>
4

3 回答 3

2

使字段类成为一个抽象类,就像 Darren 建议的那样,使“绘制”方法成为字段类的函数。

现在这是技巧,您希望输入类扩展字段,但覆盖 draw 方法。这将允许您自定义该方法的功能,并且您仍然可以从其中调用父变体。

最后,由于 textarea 类将与输入类有许多相似之处,因此请让 textarea 扩展输入。从而继承字段和输入的属性和方法。

于 2012-09-26T23:38:06.970 回答
0

让“fields”类有一个draw方法:

public function draw($msg) {
    echo $msg;
}

然后在 textarea 或输入类中放置:

parent::draw("<input>");

这减少了您拥有的方法数量,并且可以为两种类型的字段调用一种方法。

同样在您的“字段”类中,将 id 代码更改为如下所示:

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

然后在子类中:

parent::__construct(1); //Or whatever ID you want

您拥有它的方式,ID 每次设置时都是相同的值,这将导致字段的每个子类都具有相同的 id。这样每个子类将有一个单独的 ID。

也因为我很好,这一切都放在一起:

public class field {
    $id;
    public __construct($id) {
        $this->id = $id;
    }

    public function draw($msg) {
        echo $msg;
    }
}

public class input extends field {
    public __construct() {
        parent::__construct(1);
        parent::draw("<input>");
    }
}

public class textarea extends field {
    public __construct() {
        parent::__construct(2);
        parent::draw("<textarea>");
    }
}

这就是我根据你所说的把它放在一起的方式。不过,我可能弄错了您的要求。你能告诉我我主要是一个Java程序员吗?

于 2012-09-26T23:30:48.953 回答
0

目前还不清楚你想做什么。对于您给出的示例,我认为结构还可以,但是您应该进行一些更改,尤其是构造函数。我认为构造函数应该是抽象的,带有抽象方法draw()。

abstract class fields { 

   // Use a static member to keep track of id's instead of making it global
   private static $id = 0;

   // Use an instance variable to keep track of a particular instance's id
   private $myId;

   public function __construct() {
      // Increment the static ID & assign it to the instance id.
      $this->myId = self::$id++;
   }

   // Provide a public getter, so that the ID can't be changed
   // externally to this class
   public function getId() {
       return $this->myId;
   }

   public abstract draw(); // Make sure all sub classes implement a draw() method.

}

class input extends fields {
   // Don't need to call the parent constructor if you're not adding anything
   // else. It will be called automatically.

   public function draw() {
      echo '<input>';
   }
}

class textarea extends fields {
   public function draw() {
      echo '<textarea>';
   }
}
于 2012-09-26T23:41:07.120 回答