30

Java 8 インターフェースの新しい仮想拡張メソッドを見ています。

public interface MyInterface {
   default String myMethod() { 
      return "myImplementation"; 
   }
}

インターフェイスを時間の経過とともに進化させ、複数の継承を可能にするという目的は理解できますが、私には抽象クラスのように見えます。

新しい作業を行っている場合、「インターフェイス」に実装を提供するために拡張メソッドよりも優先される抽象クラスですか、それともこれら 2 つのアプローチは概念的に同等ですか?

4

5 に答える 5

34

このような構造の主な目的の 1 つは、後方互換性を維持することです。Java 言語へのクロージャの追加は非常に大きな変更であり、これを十分に活用するには更新が必要です。たとえば、 Java 8 には、ラムダと連携して機能Collectionする などのメソッドがあります。forEach()このようなメソッドを既存のCollectionインターフェースに単純に追加することは、下位互換性を損なうため、現実的ではありません。私が Java 7 実装で作成したクラスは、Collectionこれらのメソッドがないため、コンパイルできなくなりました。したがって、これらのメソッドは「デフォルト」の実装で導入されます。Scala を知っていれば、Javainterfaceがより Scala に似てきていることがわかりますtrait

インターフェイスと抽象クラスに関しては、Java 8でもこの 2 つは異なります。たとえば、インターフェイスにコンストラクターを含めることはできません。したがって、2 つのアプローチ自体は「概念的に同等」ではありません。抽象クラスはより構造化されており、関連付けられた状態を持つことができますが、インターフェイスはできません。Java 7 以下で行う場合と同様に、プログラムのコンテキストでより意味のある方を使用する必要があります。

于 2013-08-13T00:04:27.327 に答える
5
  1. 抽象クラスはラムダ式のルート クラスになることはできませんが、仮想拡張メソッドを含むインターフェイスは可能です。
  2. 抽象クラスはコンストラクターとメンバー変数を持つことができますが、インターフェイスはできません。考えられるコンストラクターの実行と、抽象クラスがラムダ式のルートになることを禁止するチェック例外のスローの可能性があると思います。

ユーザーがラムダ式を使用できるようにする API を作成する場合は、代わりにインターフェイスを使用する必要があります。

于 2013-08-13T00:02:57.433 に答える
0

抽象クラスjava-8は、以下の領域のインターフェイスでスコアを獲得します。

  1. 抽象クラスを使用すると、静的でも最終でもないフィールドを宣言し、パブリック、プロテクト、およびプライベートの具象メソッドを定義できます。インターフェイスを使用すると、すべてのフィールドが自動的に public、static、および final になり、(デフォルト メソッドとして) 宣言または定義するすべてのメソッドが public になります。

  2. 可変状態は、定数のみを持つインターフェースとは異なり、子クラスと共有/変更できます

  3. 抽象クラスを使用してTemplate_method_patternを実装できます。操作のアルゴリズムのプログラム スケルトンを定義し、いくつかのステップをサブクラスに任せます。
  4. 抽象クラスを使用してDecorator_patternを実装できます: 同じクラスの他のオブジェクトの動作に影響を与えることなく、静的または動的に個々のオブジェクトに動作を追加できる設計パターン。
于 2016-09-25T16:26:48.770 に答える
0

抽象クラスと機能インターフェースの違いは、通常のインターフェースと抽象クラスのすべての違いに似ていますが、違いの測定は、機能インターフェースにデフォルトのメソッドを設定できますが、抽象クラスには設定できないことです。これは変更され、Java 8 foreach のすべてのコレクション実装に役立ちました() およびラムダを使用したその他のパフォーマンス メソッド

package com.akhi;
public abstract class AbstractDemo {
abstract void letsRun(); // abstract valid
public String toString(); // invalid but valid in interface or functional interface

public boolean equals(Object o); // invalid but valid in interface or functional interface

public int concrete() { // Concrete is invalid in interface
    return 1;
}

public default int getMult(int a, int b) // default invalid but valid in case of functional
{
    return a * b;
}

public static int getSum(int a, int b) // static allowed
{
    return a + b;
}
}

于 2018-10-03T09:41:15.787 に答える