子类OOP的局限性

ind*_*man 22 java oop

在java中,围绕一个减少超类功能的子类设计的好方法是什么?

例如,考虑具有"See"函数的类"Man"和不应该具有该函数的子类"BlindMan",但应该具有"Man"具有的所有其他内容.

我能想出的唯一解决方案是使用抽象类"Man"和两个子类"SeeingMan"和"BlindMan",SeeinMan添加了一个"See"功能.

但是这个解决方案的问题在于,如果我现在想要添加一个"DeafMan"类 - 它会扩展什么?SeeingMan?如果那个男人既聋又瞎眼怎么办?

Dor*_*don 14

我认为在这种情况下你应该使用Composition而不是继承,或者有各种构成人类的子类.

虽然我理解你的逻辑,但BaseClass是一个契约,它保证该类型的所有类都应该遵循这种行为,拥有一个删除父方法的子类是一个很大的NO NO ..

虽然你可以抛出各种异常,但我根本不会走这条路.以这种方式思考,说我是一个只需要访问Human对象的开发人员,我期待某种行为,突然之间我调用了一个接口方法并获得了一个例外,因为我调用了它?您不应该知道派生类的实现以及何时可以或不能调用它们.

以下是一些解决方案:

让人类成为BasicHumanFunctions,VisionSystem等的组合.那么盲人只有少数几个.

class Human {
  private BasicHumanFunctions _basicFunctions; //contains breathe funcitonality.
  private VisionSystem _vision; //contains see
}

class BlindMan {
   private BasicHumanFunctions _basicFunctions;
}
Run Code Online (Sandbox Code Playgroud)

Make Human基类只包含所有人类想呼吸的相同行为等,然后创建一个HealthyHuman和一个BlindHuman等,每个创建自己的方法.然后,如果需要,您可以进一步使用HealthHuman和子类.

class Human {
   void breathe() {};
   // other Human basic functions;
} 

class HealthyHuman extends Human {
   void see() {};
   //other healthy human functions
}

class BlindHuman extends Human {
  void useCane() {};
}
Run Code Online (Sandbox Code Playgroud)

对于第二种情况,您仍然可以使用合成来共享行为:

class BlindHuman extends Human {
   private VoiceSubsystem _voice = new VoiceSybsystem();
   void speaker() {  _voice.speaker();}
}
Run Code Online (Sandbox Code Playgroud)

  • 当Exception是RuntimeException并因此出乎意料时,我认为它只是NO NO.如果接口声明了Exception,则无论如何都必须处理它.(因为在这一刻,即使看见的人也会被蒙蔽) (3认同)

小智 8

最重要的原则是利斯科夫的替代原则.

获得并应用后,您可以根据需要构建模型.

例如,你可以说一个盲人仍然看到,只有他只得到黑色(或灰色)图片.还有一个问题,即法律上失明的人,如果模糊或局部的照片,你仍然会看到一些东西.

你也可以说对象可以做的动作是看不到的.我们要做的就是看.看是观看的(成功)结果.即使有工作的眼睛,你可能会看到没有看到任何东西!盲人仍然可以通过聆听(从而听到并建立一个心理"图片")来"看到"没有眼睛或没有功能的眼睛的东西.

所以,忘记"看"和"听".使用手表和听.并期待一切.(广泛的前提条件).


Ang*_*chs 0

如果您不希望调用该函数,则可以抛出异常。

eG 在您的场景中:InablityException

像这样:

public interface Man {

    public Object see() throws InabilityException;
    public Object hear() throws InabilityException;

}

public class BlindMan implements Man {
    public Object see() throws InabilityException {
       throw new InabilityException("blind people don't see");
    }

    public Object hear() {
       return "what I hear";
    }
}
Run Code Online (Sandbox Code Playgroud)

对于聋人来说反之亦然。

class如果 Man 是 a而不是 an ,同样的事情也会发生interface

您可以(并且应该)将其与 @Pataschu 答案/sf/answers/1195643851/结合起来,并且throwif返回 false。ExceptionhasWorkingEyes()