Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/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 何时实现接口,何时扩展超类?_Oop_Inheritance_Interface_Superclass - Fatal编程技术网

Oop 何时实现接口,何时扩展超类?

Oop 何时实现接口,何时扩展超类?,oop,inheritance,interface,superclass,Oop,Inheritance,Interface,Superclass,我已经读了很多关于Java中接口和类继承的书,我知道如何做到这两个方面,我认为我对这两方面都有很好的感觉。但似乎没有人真正将两者并排进行比较,并解释何时以及为什么要使用其中一种。我没有发现很多时候实现一个接口会比扩展一个超类更好 那么什么时候实现接口,什么时候扩展超类呢?如果您只想继承子类中的方法签名(名称、参数、返回类型),请使用接口,但如果您还想继承实现代码,请使用超类。没有人 编辑:我应该提供更多的链接 情况是这样的。在下面的例子中,考虑这个< /P> interface Drivabl

我已经读了很多关于Java中接口和类继承的书,我知道如何做到这两个方面,我认为我对这两方面都有很好的感觉。但似乎没有人真正将两者并排进行比较,并解释何时以及为什么要使用其中一种。我没有发现很多时候实现一个接口会比扩展一个超类更好


那么什么时候实现接口,什么时候扩展超类呢?

如果您只想继承子类中的方法签名(名称、参数、返回类型),请使用接口,但如果您还想继承实现代码,请使用超类。

没有人

编辑:我应该提供更多的链接

情况是这样的。在下面的例子中,考虑这个< /P>
interface Drivable {
    void drive(float miles);
}

abstract class Car implements Drivable { 
    float gallonsOfGas;
    float odometer;
    final float mpg;
    protected Car(float mpg) { gallonsOfGas = 0; odometer = 0; this.mpg = mpg; }
    public void addGas(float gallons) { gallonsOfGas += gallons; }
    public void drive(float miles) { 
        if(miles/mpg > gallonsOfGas) throw new NotEnoughGasException();
        gallonsOfGas -= miles/mpg;
        odometer += miles;
    }
}

class LeakyCar extends Car { // still implements Drivable because of Car
    public addGas(float gallons) { super.addGas(gallons * .8); } // leaky tank
}

class ElectricCar extends Car {
    float electricMiles;
    public void drive(float miles) { // can we drive the whole way electric?
         if(electricMiles > miles) {
             electricMiles -= miles;
             odometer += miles;
             return;                 // early return here
         }
         if(electricMiles > 0) { // exhaust electric miles first
             if((miles-electricMiles)/mpg > gallonsOfGas) 
                 throw new NotEnoughGasException();
             miles -= electricMiles;
             odometer += electricMiles;
             electricMiles = 0;
         }
         // finish driving
         super.drive(miles);
    }
}

我发现了一些文章,特别是一些描述为什么不应该使用实现继承(即超类)的文章:


    • 我想我会举一个经典汽车的例子

      当你有一个汽车界面时,你可以创建一辆福特、一辆雪佛兰和一辆奥兹莫比尔。换句话说,您可以从汽车界面创建不同种类的汽车


      当您有一个car类时,您可以扩展car类以生成一辆卡车或一辆公共汽车。换句话说,在保留基类或超类属性的同时,向子类添加新属性。

      我认为,当使用接口来表示对象具有特定属性或行为、跨越多个继承树、并且仅为每个类明确定义时,接口最为有效

      例如,想想可比性。如果您想创建一个可与其他类进行扩展的类,它必须位于继承树的很高位置,可能在Object之后,并且它表示的属性是可以比较该类型的两个对象,但一般来说无法定义(compareTo的实现不能直接在Comparable类中,每个实现它的类都不同)

      当类定义了一些明确的内容,您知道它们具有哪些属性和行为,并且具有要传递给子类的方法的实际实现时,它们工作得最好

      因此,当您需要定义一个具体的对象(如人或汽车)时,类就可以工作,而当您需要更抽象的行为(过于笼统,不属于任何继承树,如可比较或可运行的能力)时,接口就可以更好地工作。

      使用接口来定义行为。用户(抽象)类(和子类)提供实现。它们不是相互排斥的;它们可以一起工作


      例如,假设您正在定义一个数据访问对象。您希望您的DAO能够加载数据。因此在接口上放置一个load方法。这意味着任何想要称自己为DAO的东西都必须实现load。现在假设您需要加载a和B。您可以创建一个参数化的泛型抽象类(泛型)提供负载如何工作的概要。然后,将抽象类细分为子类,以提供A和B的具体实现。

      如果要定义合约,请使用接口。。例如,X必须取Y并返回Z。这与代码如何执行无关。一个类可以实现多个接口。

      如果要在非抽象方法中定义默认行为,则使用抽象类,以便最终用户可以重用它,而无需反复重写。一个类只能从另一个类扩展。只有抽象方法的抽象类可以像接口一样定义良好。具有任何抽象方法都可以识别为模式(请参阅一些实际示例)


      反过来,抽象类可以完美地实现接口,只要您想让最终用户自由定义默认行为。

      如果派生类的类型相同,您可以考虑从一个超类进行扩展。我的意思是,当一个类扩展一个抽象类时,它们都应该是相同的类型,唯一不同的是因为超类有更一般的行为,而子类有更具体的行为。接口是一个完全不同的概念。当一个类实现一个接口时,它要么公开一些API(契约)或者获得特定的行为。举个例子,我会说汽车是一个抽象类。你可以从中扩展很多类,比如福特、雪佛兰等等,它们都是汽车类型。但是如果你需要特定的行为,比如说你需要在汽车中安装GPS,那么具体的类,比如福特应该实现GPS接口。

      主要的使用抽象类和接口的ason是不同的

      当您的类对于一组方法具有相同的实现,但在一些方法中有所不同时,应该使用抽象类

      这可能是一个不好的例子,但Java框架中抽象类最明显的用途是在Java.io类中。
      OutputStream
      只是一个字节流。该流的去向完全取决于您使用的是
      OutputStream
      的哪个子类……
      FileOutputStream
      pipedoutstream
      >,从
      java.net.Socket
      getOutputStream
      方法创建的输出流

      注意:java.io还使用Decorator模式包装其他流/读/写器中的流

      当您只想保证一个类实现一组方法,而不关心如何实现时,应该使用接口

      接口最明显的用途是在集合框架内

      我不在乎
      列表如何添加/删除元素,只要我可以调用
      add(something)
      get(0)