[英]PHP Abstract ; Is this the right way to use an abstract class?
我只是想知道我是否走在正确的道路上。 使大多数函数抽象似乎没有必要,因为数据几乎相同。 这是一种无效的方法吗?
<?php
abstract class Model_Tasks {
/**
* Database object
*
* @access protected
*/
protected $db;
/**
* User ID
*
* @access protected
*/
protected $uid;
/**
* Data array
*
* @access protected
*/
protected $data;
/**
* SQL Query
*
* @access protected
*/
protected $query;
/**
* __construct
*
* @access protected
*/
protected function __construct($query) {
$this->db = Model_DB::getInstance();
$this->uid = $_SESSION['uid'];
$this->query = $query;
$this->getTasks();
}
/**
* getTasks
*
* @param string
* @access abstract protected
*/
protected function getTasks() {
$result = $this->db->prepare($this->query);
$result->execute(array(
':uid' => $this->uid
));
$this->data =& $result->fetchAll();
$this->taskCount = $result->rowCount();
}
/**
* constructTask
*
* Build the HTML of a task
*
* @param int
* @param int
* @param string
* @param string
* @access protected
*/
protected function constructTask(
$id, $cost, $title, $checked = 0
) {
$cost = money_format('$%i', $cost);
$title = stripslashes($title);
return '
<label class="task">
<input type="checkbox" name="done[]" rel="'.$id.'" '.($checked?'checked="checked"':'').' />
<code>'.$cost.'</code> — '.$title.'
</label>'."\n";
}
/**
* generateOutput
*
* Call by key [pending, completed] and return the constructed tasks
*
* @param bool
* @access final public
*/
final public function generateOutput($checked) {
try {
if(!is_bool($checked)) throw new Exception('generateOutput must contain a boolean variable');
if(!isset($this->data)) throw new Exception('Array has not been set.');
else $data = $this->data;
} catch(Exception $e) {
die('<pre>'.$e->getMessage().'<hr />'.$e->getTraceAsString());
}
if(is_array($data)): foreach($data AS &$r)
$str .= $this->constructTask($r['id'], $r['cost'], $r['title'], $checked);
else:
$str = '<label class="tasks"></label>';
endif;
return $str;
}
}
// ------------------------------------------------------------------------
/**
* pendingTasks
*
* @access public
*/
class pendingTasks extends Model_Tasks {
public $taskCount;
public function __construct() {
$query = '
SELECT id, title, cost
FROM tasks
WHERE (
status IS FALSE
AND uid = :uid
) ORDER BY cost DESC
';
parent::__construct($query);
}
}
/**
* completedTasks
*
* @access public
*/
class completedTasks extends Model_Tasks {
public function __construct() {
$query = '
SELECT id, title, cost
FROM tasks
WHERE (
status IS TRUE
AND uid = :uid
) ORDER BY id DESC
LIMIT 7
';
parent::__construct($query);
}
}
它只是打印出具有特定查询的任务,并返回一个关联数组。
“这是一种无效的方法吗?”
不。您的代码正确使用抽象。 您可以集中常见逻辑,但是通过将父类声明为抽象,您正在强制通过子类(扩展您的抽象,父类)来完成类的实例化,这很有效。
一点建议:
$this->uid = $_SESSION['uid'];
以这种方式声明成员变量会破坏封装。 我建议你通过调用代码分配这样的成员变量,而不是在构造函数中。
从抽象类继承时,父类声明中标记为abstract的所有方法都必须由子类定义; 此外,必须使用相同(或限制较少)的可见性来定义这些方法。 例如,如果将抽象方法定义为protected,则必须将函数实现定义为protected或public,而不是private。 此外,方法的签名必须匹配,即类型提示和所需参数的数量必须相同。 这也适用于PHP 5.4的构造函数。 在5.4构造函数签名可能不同之前。 - php.net
在您的实现中,构造函数的签名是不同的..
这是一个使用抽象类的时间的真实例子:小部件。
我有一个小部件模型,它具有创建,编辑,保存或呈现小部件所需的大部分功能。 但是,有两个基本指标我需要这个类是抽象的:
edit()
方法和一个render()
方法,因为照片小部件具有不同的属性,并且应该与tweet小部件显示不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.