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
Oop 彼得·迈耶的后续行动';s";“编程到接口”;回答_Oop_Language Agnostic_Interface - Fatal编程技术网

Oop 彼得·迈耶的后续行动';s";“编程到接口”;回答

Oop 彼得·迈耶的后续行动';s";“编程到接口”;回答,oop,language-agnostic,interface,Oop,Language Agnostic,Interface,这是对@Peter Meyer在此问题()中给出的答案的后续问题 首先,让我首先说,我不愿意把这变成一个新问题。但是(我喜欢stackoverflow,但我在这里必须有点挑剔)1)我不能私下给Peter Meyer发信息(阅读:),2)我不能发布“后续”问题(阅读:),3)这个问题被锁定以避免“爆炸药丸”,唉,我没有足够的声誉在那里提问 所以,我必须提出一个新问题 在这篇文章中,Peter Meyer展示了一个精彩有趣的例子,说明了何时使用接口以及为什么对接口编程很重要 我的问题是:使用包装器类

这是对@Peter Meyer在此问题()中给出的答案的后续问题

首先,让我首先说,我不愿意把这变成一个新问题。但是(我喜欢stackoverflow,但我在这里必须有点挑剔)1)我不能私下给Peter Meyer发信息(阅读:),2)我不能发布“后续”问题(阅读:),3)这个问题被锁定以避免“爆炸药丸”,唉,我没有足够的声誉在那里提问

所以,我必须提出一个新问题

在这篇文章中,Peter Meyer展示了一个精彩有趣的例子,说明了何时使用接口以及为什么对接口编程很重要

我的问题是:使用包装器类不是解决问题的另一种方法吗

你不能写:

interface IPest {
   void BeAnnoying();
}


class HouseFly inherits Insect implements IPest {
  void FlyAroundYourHead();
  void LandOnThings();

  void BeAnnoying() {
    FlyAroundYourHead();
    LandOnThings();
  }
}

class Telemarketer inherits Person implements IPest {
  void CallDuringDinner();
  void ContinueTalkingWhenYouSayNo();

  void BeAnnoying() {
     CallDuringDinner();
     ContinueTalkingWhenYouSayNo();
  }
}
class DiningRoom {

  DiningRoom(Person[] diningPeople, IPest[] pests) { ... }

  void ServeDinner() {
    when diningPeople are eating,

      foreach pest in pests
        pest.BeAnnoying();
  }
}
这样:

class IPest {
  HouseFly houseFly;
  public IPest(HouseFly houseFly) {
    this.houseFly = houseFly;
  }
  Telemarketer telemarketer;
  public IPest(Telemarketer telemarketer) {
    this.telemarketer = telemarketer;
  }
  void BeAnnoying() {
    if(houseFly != null)
      houseFly.BeAnnoying();
    else
      telemarketer.BeAnnoying();
  }
}


class HouseFly inherits Insect {
  void FlyAroundYourHead();
  void LandOnThings();

  void BeAnnoying() {
    FlyAroundYourHead();
    LandOnThings();
  }
}

class Telemarketer inherits Person {
  void CallDuringDinner();
  void ContinueTalkingWhenYouSayNo();

  void BeAnnoying() {
     CallDuringDinner();
     ContinueTalkingWhenYouSayNo();
  }
}
class DiningRoom {

  DiningRoom(Person[] diningPeople, IPest[] pests) { ... }

  void ServeDinner() {
    when diningPeople are eating,
      foreach pest in pests
        pest.BeAnnoying();
  }
}
?

尽管我将其标记为语言不可知论,但我确实在“Java化”这个问题,因为这是我最熟悉的,所以请原谅我。但在我看来,使用接口方法有缺点。例如,如果您想为不同的类型重写“toString()”方法,根据它是被表示为“IPest”还是“HouseFly”来返回不同的值,那么在接口中您不能这样做。您不能单独为“HouseFly”指定与使用接口实现IPest接口的HouseFly不同的toString值(因为HouseFly总是通过类定义实现接口)。包装类将为您提供比接口更广泛的功能

举例说明:假设您希望在列表中显示所有“IPests”,但希望列表中的每个“IPests”上都有一个区别标记,以显示该害虫是苍蝇还是电话推销员。然后使用包装器类,这将很容易:

class IPest {
  HouseFly houseFly;
  public IPest(HouseFly houseFly) {
    this.houseFly = houseFly;
  }
  Telemarketer telemarketer;
  public IPest(Telemarketer telemarketer) {
    this.telemarketer = telemarketer;
  }
  void BeAnnoying() {
    if(houseFly != null)
      houseFly.BeAnnoying();
    else
      telemarketer.BeAnnoying();
  }
  public String toString() {
    return (houseFly == null? "(T) " + telemarketer.toString() : "(F) " + houseFly.toString()) + 
  }
}
然后,在另一个地方,如果您有一个列表来单独表示家蝇(不是作为IPest而是作为家蝇),那么您可以为toString()指定不同的值

这不限于toString(),而是这些类可能具有的任何其他方法,当对象表示为IPest时,您可能希望覆盖这些方法以提供不同的功能,而当对象表示为家蝇或电话销售员时,则可能需要覆盖这些方法

我希望我的问题有意义

我的理论是:如果您正在编程一个API或任何人都会使用的东西,您应该避免使用具体的类,并尝试使用接口。但是,如果您直接编写客户机代码,并且对代码重用没有任何期望(或可能性),那么“编程到接口”似乎没什么大不了的


我期待任何反馈。我是不是离基地太远了?我写代码很糟糕吗?希望Peter Meyer能给我一些建议…

这会让代码变得更加丑陋,但没有明显的好处。(这读起来有点刺耳,这不是我想要的…+1的实际问题)

最大的缺点是你的网上课程。当您继续添加可能的有害程序时,这个类会变得庞大,并且由于未使用的变量和代码而变得臃肿。如果您有30种不同种类的有害生物,那么您的IPest类比您的示例中的2种增加了15倍,并且有大量额外的代码来支持所有这些类

更糟糕的是,这段代码的绝大多数实际上与实例化的对象无关。如果IPest应该表示一个家蝇,那么有几个实例变量(每个实例变量对应于另一种类型的IPest)都是空的,还有大量未使用的代码。更糟糕的是,如果IPest的多个值不为null,会发生什么情况?这是怎么一回事?(布伦德飞电话推销员!)

将此与纯接口进行比较,纯接口不会随着更多类的实现而变大(因为它不在乎)

最后,我认为用两个(或更多)对象(如家蝇对象和IPest对象)来表示单个概念想法(如一只苍蝇)以及更多想要添加更多功能的对象通常是没有用的(或一个好主意)。对于每个包装器,添加另一个对象,这是另一个可能要跟踪和更新的对象


这并不是说不可能有像这样的非常特殊的情况不是一个好主意…但我在这里没有看到它,因为我上面描述的原因。

不久,你又添加了14种害虫,你的IPest取决于它们。此外,IPest的每个用户也都依赖于它们。如果你是你自己最大的敌人,欢迎你尝试一下。。。没有问题的苛刻。我的例子来自我最近遇到的一个问题,这就是为什么我问这个问题。我面临的问题是:我的程序处理“转介”,这些转介可以来自人(一个对象)或公司(另一个对象)。我们有几个屏幕,这些对象并排放置在列表和表格上,就像它们是一个对象一样。但是,我们希望能够在toString方法中区分哪些是。如果没有包装器类,我无法思考如何解决这个问题。也许我应该调整我的想法,只有在绝对必要的时候才使用这个包装器类方法。没错,随着可能要包装的对象列表的增加,类的复杂性也随之增加。尽管如此,我仍然认为我的理论是正确的,在非API代码中,这可能是一个没有实际意义的对话。。