Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用类的层次结构,其中子类具有一些独特的特性_Php_Oop - Fatal编程技术网

Php 使用类的层次结构,其中子类具有一些独特的特性

Php 使用类的层次结构,其中子类具有一些独特的特性,php,oop,Php,Oop,这是我有时遇到的一个设计问题。假设我有一组相关的类,有一些共同的特性和一些独特的特性 interface TableCell { public function setContent($content); } interface HTMLTableCell extends TableCell { public function setID($id); public function setClass($class); } interface CSVTableCell ex

这是我有时遇到的一个设计问题。假设我有一组相关的类,有一些共同的特性和一些独特的特性

interface TableCell {
    public function setContent($content);
}
interface HTMLTableCell extends TableCell {
    public function setID($id);
    public function setClass($class);
}
interface CSVTableCell extends TableCell {
    public function setQuoted($quoted);
}
然后我有一些类需要与集合中的任何对象交互。使用常用的方法很容易。但我希望该类也能够使用唯一的方法,当它们可用时:

class NumberCell {
    public function render(TableCell $cell) {
        $cell->setContent("123.45");
        // if this is a HTMLTableCell
        $cell->setClass("number");
    }
}

最好的处理方法是什么?在运行时检查类型似乎有点麻烦。我愿意改变设计。

因为CSV和HTML都是不同的输出格式,所以为这些格式设置专用的NumberCell是有意义的。换句话说,
HTMLNumberCell
CSVNumberCell

class HTMLNumberCell {
    public function render(TableCell $cell) {
        $cell->setContent("123.45");
        $cell->setClass("number");
    }
}

或者使用一种方法,但是你必须在呈现之前找到一种方法来实例化它。

接口是OO中可能的最高限制级别。也就是说,您不能让某些东西使用它不知道的方法的接口。这就是为什么它的所有方法都是公开的。对于HTMLTableCell,sedID()和setClass()本质上是绑定在一起的。相反,您应该有一个更高的执行方法来包装对这些方法的调用(以及CSV的相应setQuoted()


这是战略模式的一个例子。实际上,答案是TableCell接口封装得不够。TableCell类的方法对上下文(调用者,在本例中为NumberCell)应该是完全透明的。

我将尝试找到更多可以接受的方法,尽管我认为我已经接受了所有回答我问题的方法。你的意思是我应该试着将setID和setQuoted之类的东西作为通用TableCell接口的一部分吗?我所遇到的问题是,其中一些仅对某个子界面(例如HTML或CSV)有意义。所以我不太愿意把通用接口和具体实现细节混在一起。不,这不是我要说的。接口应该非常稀疏。我想说的是你应该有一个方法,比如“setContent()”或者你有什么。例如,对于Html类中的实现,它将调用setID()和setClass(),对于CSV,它将调用setQuoted()。