确保一个类至少实现一个方法

时间:2013-05-15 21:47:18

标签: php oop

方案

这绝不是真的,所以拿一粒盐的例子。这是一种传达场景的简单方法。话虽如此,假设我们有以下类定义。

interface iVehicle {
   public function getDescriptionFormat1();
   public function getDescriptionFormat2(); 
}

class VehicleDescription {
   ...
}

class TruckDescription extends VehicleDescription implements iVehicle {
  ... 
}

class CarDescription extends VehicleDescription implements iVehicle {
  ...
}

问题

类CarDescription和TruckDescription可以实现一种或两种描述格式。当仅需要一个时,覆盖两个类中的两个方法似乎都是错误的。实施这种限制的正确方法是什么?或者,您可以尝试向我推销这是一个糟糕的设计决定。

修改 - 的 我担心我的例子太模糊了。我很抱歉。这两种描述或多或少是不同的数据结构,而不是字符串。可能会返回一个数组,表示详细描述长度为3列,另一个可能会返回一个包含2列的更基本的描述表

4 个答案:

答案 0 :(得分:2)

要么对两种情况都使用一种方法,并给它一个参数来确定它应该如何表现,例如。

interface iVehicle {
    public function getDescription($Format);
}

class CarDescription extends VehicleDescription implements iVehicle {
    public function getDescription($Format) {
        switch ($Format) {
            case 1:
                // Do what needs to be done
                break;
            case 2:
                // Do what needs to be done
                break;
            default:
                throw new Exception('Error');
                break;
    }
}

或者您使用两个接口,该类为它实现适当的接口(或两者兼而有之。)

interface iVehicle1 {
    public function getDescriptionFormat1();
}
interface iVehicle2 {
    public function getDescriptionFormat2();
}

// Let's skip forward

class CarDescription extends VehicleDescription implements iVehicle1, iVehicle2 {
    // ...
}

当然,在后一种情况下,你仍然必须使用不同的方法名称,以防该类实现这两个接口。

答案 1 :(得分:1)

您应该只使用一个getDescriptionFormat()方法,并为VehicleDescription类的不同子类提供适当的实现。

修改

我刚看了你对你的问题的评论,这些类可以实现这两种方法。如果这是你想要的,你的例子已经可以了。您可以做的一件事是在VehicleDescription类中提供空实现。

至于如何确保在这种情况下至少实现其中一种方法,我认为这不可行,但如果我错了,请纠正我:)

答案 2 :(得分:1)

接口可以被视为合同。任何实现该接口的类都保证它将提供指定的函数。

然而,完全取决于实现类如何实际执行此操作。在您的示例TruckDescriptionCarDescription中,由于各种原因可能需要返回不同的描述格式,因此请实施getDescriptionFormat1()& getDescriptionFormat2()以不同的方式。

基本上这意味着您可能只需要在接口中使用getDescriptionFormat(),然后实现类就可以根据需要实现该功能。

听起来好像你应该标准化返回的内容。也许是一个可以封装描述的Format Class?我现在只是猜测,因为我不知道任何细节,但我认为这就是我要考虑的内容。

答案 3 :(得分:0)

以下是我将如何解决这个问题。

interface Describable {
   public function getDescription(); 
}

interface Sellable {
    public function getPrice();
}

// abstract class - can't create an instance but can hold shared methods and property definitions
abstract class Vehicle implements Describable, Sellable {
    abstract public function getDescription();

    // this can't be overloaded
    final public function getPrice(){
        // code for get price
    }
    public function getColorOptions(){
        // this can be overloaded
    }
}

// concrete class that just uses the abstracts' definitions
class Car extends Vehicle {
    public function getDescription(){
        // overload for cars
    }
}

// concrete class that overloads one of the properties
class Truck extends Vehicle {
    public function getDescription(){
        // overload for trucks
    } 
}


class FlyingCar extends Car {
    public function getDescription(){
        // Flying cars need a whole new description
    }

}

基本上这显示了一个必须重载的方法(getDescription由于它被定义为抽象)

一个不能超载的(由于它被定义为最终的getPrice)

和在摘要上定义的可以重载或使用默认实现的那个。