方案
这绝不是真的,所以拿一粒盐的例子。这是一种传达场景的简单方法。话虽如此,假设我们有以下类定义。
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列的更基本的描述表
答案 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)
接口可以被视为合同。任何实现该接口的类都保证它将提供指定的函数。
然而,完全取决于实现类如何实际执行此操作。在您的示例TruckDescription
和CarDescription
中,由于各种原因可能需要返回不同的描述格式,因此请实施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)
和在摘要上定义的可以重载或使用默认实现的那个。