インタフェースと抽象クラスの違いは何ですか?
インターフェースは コントラクト :インターフェースを書いている人は " ちょっと、そのように見えるものを受け入れる "、そしてインターフェースを使っている人は " OK、クラスI writeはそのように見えます "。
インターフェースは空のシェルです 。メソッドのシグネチャのみが存在します。これは、メソッドに本体がないことを意味します。インターフェースは何もできません。それは単なるパターンです。
例えば(疑似コード):
// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();
int getFuel();
}
// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{
int fuel;
void run()
{
print("Wrroooooooom");
}
int getFuel()
{
return this.fuel;
}
}
インターフェースを実装することは、それがクラスではなく、単なる名前の集まりであるため、非常に少ないCPUを消費します、そしてそれ故にするべき高価な検索がありません。組込み機器の場合のように重要な場合には最適です。
抽象クラスは、インタフェースとは異なり、クラスです。それらを継承するときに行うべきルックアップがあるので、それらは使用するのがより高価です。
抽象クラスはインタフェースによく似ていますが、それ以上のものがあります。それらの動作を定義できます。 「これらのクラスはそのように見えるべきであり、それらは共通しているので、空白を埋めてください」と言う人に関するものです。
例えば:
// I say all motor vehicles should look like this:
abstract class MotorVehicle
{
int fuel;
// They ALL have fuel, so lets implement this for everybody.
int getFuel()
{
return this.fuel;
}
// That can be very different, force them to provide their
// own implementation.
abstract void run();
}
// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}
抽象クラスとインタフェースは異なる概念であると想定されていますが、実装によってはその文が正しくない場合があります。時々、彼らはあなたが彼らがいると思うものでさえありません。
Javaでは、この規則が強く適用されますが、PHPでは、インターフェイスはメソッドが宣言されていない抽象クラスです。
Pythonでは、抽象クラスはABCモジュールから得られるプログラミングのトリックであり、実際にはメタクラス、したがってクラスを使用しています。そしてインターフェースはこの言語ではアヒルの型付けにもっと関係しており、それは規約と記述子を呼び出す特別なメソッド(__method__メソッド)の組み合わせです。
プログラミングと同じように、理論、実践、そして他の言語での実践があります:-)
抽象クラス と interface の間の主な技術的な違いは:
抽象クラスは 定数、メンバ、メソッドスタブ(ボディなしのメソッド)、および定義済みメソッド を持つことができますが、インタフェースは 定数 および メソッドスタブ のみを持つことができます。
抽象クラスのメソッドとメンバは 任意の可視性 で定義できますが、インタフェースのすべてのメソッドはpublic
として定義する必要があります(デフォルトではpublicとして定義されています)。
抽象クラスを継承する場合、 concrete child class は抽象メソッド を定義する必要があります。一方、抽象クラスは別の抽象クラスを拡張でき、親クラスの抽象メソッドは継承する必要はありません。定義済み。
同様に、他のインタフェースを拡張するインタフェースは 親インタフェースからのメソッド の実装を担当しません。これは、インタフェースが実装を定義できないためです。
子クラスは 単一のクラス (抽象または具象)を拡張することしかできませんが、インタフェースは拡張できますまたはクラスは 他の複数のインタフェースを実装できます 。
子クラスは と同じかそれより制限の緩い可視性 で抽象メソッドを定義できますが、インタフェースを実装するクラスはまったく同じ可視性(public)でメソッドを定義しなければなりません。
インタフェースは機能の定義/シグネチャのみを含み、共通の機能と共通のシグネチャがある場合は抽象クラスを使用する必要があります。抽象クラスを使用することによって、動作と機能の両方を同時に提供できます。抽象クラスを継承する別の開発者は、空白を埋めるだけでよいので、この機能を簡単に使用できます。
http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html
http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.htmlhttp://www.dotnetbull.com/ 2011/11/Cのインターフェイスは何ですか - net.html
説明はここで見つけることができます: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm
抽象クラスは、プログラマによって部分的にのみ実装されているクラスです。 1つ以上の抽象メソッドを含めることができます。抽象メソッドは、単にメソッドを子クラスで実装する必要があることをプログラマに伝えるために役立つ[定義]関数定義です。
インターフェースは抽象クラスに似ています。実際、インターフェースはクラスや抽象クラスと同じ名前空間を占めています。そのため、クラスと同じ名前のインターフェイスを定義することはできません。インターフェースは完全に抽象クラスです。そのメソッドのどれも実装されておらず、そこからサブクラス化するクラスの代わりに、それはそのインタフェースを実装すると言われています。
とにかく、私はこのインターフェースの説明がやや紛らわしいと思います。より一般的な定義は次のとおりです。 インタフェースは、実装クラスが満たすべき規約を定義します。インターフェイス定義は、実装コードを含まない、パブリックメンバーのシグネチャで構成されています。
私はすでに多くの答えで述べられている違いを強調したくありません(インターフェース内の変数に対するpublic static final修飾子および抽象クラス内の保護されたプライベートメソッドのサポートに関して)
簡単に言えば、私は言いたいと思います:
interface: 複数の無関係なオブジェクトによるコントラクトを実装する
抽象クラス: 複数の関連オブジェクト間で同じまたは異なる動作を実装する
Oracleから - -
抽象クラスの使用を検討してください if:
インターフェースの使用を検討してください if:
Serializable
インターフェースを実装できます。抽象クラスは、具象クラスとの「関係」を確立します。インタフェースはクラスに "持つ"機能を提供します。
あなたがプログラミング言語としてJava
を探しているなら、ここにもう少しの更新があります:
Java 8では、interface
メソッド機能を提供することによって、abstract
クラスとdefault
クラスの間のギャップをある程度まで減らしました。 インタフェースにメソッドの実装がありません は現在は無効です。
詳しくはこのドキュメント ページ を参照してください。
よりよく理解するためにコード例のためにこのSE質問を見てください。
いくつかの重要な違い:
テーブルの形で:
As Joeがjavapapersから述べた :
1.主な違いは、Javaインタフェースのメソッドは暗黙的に抽象的であり、実装ができないことです。 Java抽象クラスはデフォルトの振る舞いを実装するインスタンスメソッドを持つことができます。
2.Javaインターフェースで宣言された変数は、デフォルトではfinalです。抽象クラスは、最終的ではない変数を含むことがあります。
3.Javaインターフェースのメンバーはデフォルトでパブリックです。 Java抽象クラスは、private、、protectedなどのクラスメンバーの通常のフレーバーを持つことができます。
4.Javaインターフェイスは、キーワード「implements」を使用して実装する必要があります。 Java抽象クラスは、キーワード「extends」を使用して拡張する必要があります。
5.インタフェースは他のJavaインタフェースのみを拡張でき、抽象クラスは他のJavaクラスを拡張して複数のJava インタフェースを実装できます。
6.A Javaクラスは複数のインタフェースを実装できますが、拡張できるクラスは1つだけです。
7.Interfaceは絶対に抽象的であり、具体化することはできません。 Java抽象クラスもインスタンス化できませんが、 main()が存在する場合は呼び出すことができます。
8.Java抽象クラスと比較すると、Javaインターフェースは追加の間接参照を必要とするため低速です。
主なポイントはそれです:
私は300階建ての建物を建設しています
建物の青写真 インターフェース
200階建ての建物 - 部分的に完成しました--- abstract
建築工事完了 - コンクリート
インタフェース
抽象
DurgaJobsウェブサイトから撮影
継承階層で多態性の振る舞いを提供したい場合は、抽象クラスを使用してください。
あなたが完全に無関係であるクラスのために多相的な振舞いをしたいときは、インタフェースを使用してください。
もう一度この質問に取り組みましょう。
最初に知っておくべきことは、1/1と1 * 1が同じ結果になることですが、乗算と除算が同じということではありません。明らかに、彼らはいくつかの良い関係を保持していますが、あなたは両方が違うことに注意してください。
私は主な違いを指摘します、そして、残りはすでに説明されました:
抽象クラスはクラス階層をモデル化するのに役立ちます。どのような要件を一目見ただけでも、 正確に は何を構築するのかを部分的に明確にしていますが、 何を構築するのかを知っています。 そしてあなたの抽象クラスはあなたの基本クラスです。
インタフェースは、他の階層やクラスに自分ができることを知らせるのに便利です。そして、あなたが私が何か能力があると言うとき、あなたはその能力を持っていなければなりません。インタフェースは、それがクラスが同じ機能を実装することを強制するものとしてそれをマークします。
実はとても簡単です。
あなたは、抽象メソッドを持つことだけが許されるクラスとしてインターフェースを考えることができます。
そのため、インターフェイスは「宣言」することしかできず、クラスに持たせる動作を定義することはできません。
抽象クラスを使用すると、(抽象メソッドを使用して)宣言したり、(完全なメソッド実装を使用して)クラスに必要な動作を定義したりできます。
そして通常のクラスでは、クラスに持たせたい振る舞いやアクションを定義することはできません。
最後に一つだけ、
Javaでは、複数のインタフェースを実装できますが、拡張できるのは1つだけです(Abstract ClassまたはClass)...
これは、定義された振る舞いの継承がクラスごとに1つのみを許可するように制限されることを意味します。つまり、クラスA、B、Cの振る舞いをカプセル化するクラスが必要な場合多重継承を持つ方法についてのちょっとしたラウンド...
一方、インターフェースでは、単純に実行できます。インターフェースCはA、Bを実装します。
だから事実上Javaは "宣言された振る舞い"すなわちインターフェースでのみ多重継承をサポートし、定義された振る舞いを持つ単一継承のみをサポートします。
うまくいけば、それは理にかなっています。
インタフェースと抽象クラスの比較は間違っています。代わりに他に2つの比較があるべきです:1) インタフェース対クラス および2) 抽象対最終クラス 。
インタフェース は2つのオブジェクト間の規約です。例えば、私は郵便配達員であり、あなたは配達するためのパッケージです。私はあなたがあなたの配送先住所を知っていることを期待します。誰かが私にパッケージを渡すとき、それは配達先住所を知らなければなりません:
interface Package {
String address();
}
クラス は契約に従うオブジェクトのグループです。例えば、私は "Box"グループの箱であり、郵便配達員が要求する契約に従います。同時に私は他の契約にも従います。
class Box implements Package, Property {
@Override
String address() {
return "5th Street, New York, NY";
}
@Override
Human owner() {
// this method is part of another contract
}
}
抽象クラス は不完全なオブジェクトのグループです。彼らはいくつかの部分を欠場するので、それらは使用することができません。たとえば、私は抽象的なGPS対応ボックスです - 地図上で自分の位置を確認する方法を知っています。
abstract class GpsBox implements Package {
@Override
public abstract String address();
protected Coordinates whereAmI() {
// connect to GPS and return my current position
}
}
このクラスが他のクラスによって継承/拡張されている場合は、非常に便利です。しかし、それ自体では - オブジェクトを持つことはできないので無駄です。抽象クラスは最終クラスの要素を構築することができます。
Final class は完全なオブジェクトの集まりで、使うことはできますが変更することはできません。彼らは正確にどのように働くべきかそして何をすべきかを知っています。例えば、私はいつもその構築中に指定されたアドレスに行くBoxです:
final class DirectBox implements Package {
private final String to;
public DirectBox(String addr) {
this.to = addr;
}
@Override
public String address() {
return this.to;
}
}
JavaやC++のようなほとんどの言語では、抽象クラスでも最終クラスでもなく、 クラスのみ を持つことができます。そのようなクラスは継承することもインスタンス化することもできます。しかし、これが厳密にはオブジェクト指向のパラダイムと一致しているとは思いません。
繰り返しますが、インターフェイスを抽象クラスと比較するのは正しくありません。
要するに違いは次のとおりです。
Interface および Abstract Class の構文上の違い
今のインターフェースで:
public static
- サポートpublic abstract
- サポートpublic default
- サポートprivate static
- サポートprivate abstract
- コンパイルエラーprivate default
- コンパイルエラーprivate
- サポート
唯一の違いは、一方が多重継承に参加でき、他方が参加できないことです。
インタフェースの定義は時間とともに変化しました。あなたはインターフェースが単にメソッド宣言だけを持ち、単なる契約であると思いますか?静的な最終的な変数やJava 8以降のデフォルトの定義はどうでしょうか。
ダイヤモンドの問題 多重継承を伴う/のためにインターフェースがJavaに導入されましたが、それが実際に意図していることです。
インタフェースは多重継承の問題を解決するために作られたコンストラクトで、抽象メソッド、デフォルトの定義、そして静的な最終変数を持つことができます。
を参照してください。Javaは、単に契約になることを目的としているのに、静的な最終変数をインターフェイスで許可するのはなぜですか。。
インターフェイス:ターン(左折、右折)
抽象クラス:ホイール.
クラス:ステアリングホイール、Wheelから派生、Interface Turnを公開
一つは多様なものに渡って提供できる行動を分類するためのものであり、もう一つはモノのオントロジーをモデル化するためのものです。
複数のクラスで使用できる一般的なメソッドがある場合は抽象クラスに行きます。 そうでなければ、クラスがある明確な青写真をたどるようにしたいのであれば、インターフェースに行きます。
次の例はこれを示しています。
Javaの抽象クラス:
abstract class animals
{
// They all love to eat. So let's implement them for everybody
void eat()
{
System.out.println("Eating...");
}
// The make different sounds. They will provide their own implementation.
abstract void sound();
}
class dog extends animals
{
void sound()
{
System.out.println("Woof Woof");
}
}
class cat extends animals
{
void sound()
{
System.out.println("Meoww");
}
}
以下は、Javaのインターフェースの実装です。
interface Shape
{
void display();
double area();
}
class Rectangle implements Shape
{
int length, width;
Rectangle(int length, int width)
{
this.length = length;
this.width = width;
}
@Override
public void display()
{
System.out.println("****\n* *\n* *\n****");
}
@Override
public double area()
{
return (double)(length*width);
}
}
class Circle implements Shape
{
double pi = 3.14;
int radius;
Circle(int radius)
{
this.radius = radius;
}
@Override
public void display()
{
System.out.println("O"); // :P
}
@Override
public double area()
{
return (double)((pi*radius*radius)/2);
}
}
一言で言えばいくつかの重要なキーポイント:
Javaインターフェースで宣言された変数はデフォルトでfinalです。抽象クラスは最終的ではない変数を持つことができます。
Javaインタフェースで宣言された変数は、デフォルトでは静的です。抽象クラスは非静的変数を持つことができます。
Javaインタフェースのメンバは、デフォルトでパブリックです。 Java抽象クラスは、private、protectedなどのクラスメンバーの通常のフレーバーを持つことができます。
実際の質問に対する答えではありませんが、違いの答えがわかれば、それぞれの場合のジレンマを入力します。インタフェースまたは要約を使用する場合クラス?両方を使うのはいつ?
私はOOPの知識が限られていましたが、文法の形容詞に相当するものとしてインターフェースを見ることは今まで私のために働いていました(この方法が間違っているなら私を修正してください)たとえば、インターフェイス名は、クラスに付与できる属性や機能に似ており、クラスにはそれらの多くを含めることができます。ISerializable、ICountable、IList、ICacheable、IHappyなどです。
継承は2つの目的で使用されます。
オブジェクトが親タイプのデータメンバーとメソッドの実装をそれ自身のものと見なすことを可能にします。
あるタイプのオブジェクトへの参照が、スーパータイプオブジェクトへの参照を期待するコードによって使用されることを可能にします。
一般化多重継承をサポートする言語/フレームワークでは、型を「インタフェース」または「抽象クラス」として分類する必要性はほとんどありません。ただし、一般的な言語やフレームワークでは、ある型が他の型の任意の数に置き換え可能であっても、ある型が他の型のデータメンバまたはメソッド実装を自分のものと見なすことができます。
抽象クラスはデータメンバとメソッド実装を持つことができますが、他のクラスから継承しないクラスによってのみ継承することができます。インタフェースは、それを実装する型にほとんど制限を設けませんが、データメンバやメソッド実装を含めることはできません。
型が多くの異なることに代用可能であることが役に立つ場合があります。オブジェクトが親タイプのデータメンバーとメソッドの実装を独自のものと見なすと便利な場合があります。インタフェースと抽象クラスを区別することで、これらの各能力を最も関連性が高い場合に使用できます。
キーポイント:
利点:
ここに詳細を見つけます... http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/ /
interface と abstract classの間には明らかな違いがあります。
インターフェース
抽象クラス
抽象クラスは抽象メソッドと非抽象メソッドを含みます。
抽象クラスを継承したときに、ユーザーにすべてのメソッドの実装を強制することはしません。
プリミティブと非プリミティブを含むすべての種類の変数を含みます
抽象キーワードを使用して宣言してください。
抽象クラスのメソッドとメンバは、任意の可視性で定義できます。
子クラスは単一クラス(抽象クラスまたは具象クラス)のみを拡張できます。
まとめるための最短の方法はinterface
name__が次のようになることです。
default
name__およびstatic
name__メソッドを除き、完全に抽象的です。 default
name__およびstatic
name__メソッドの定義(メソッドシグネチャ+実装)はありますが、他のメソッドの宣言(メソッドシグネチャ)しかありません。interface
name__sを実装でき、interface
name__は複数のinterface
name__sを継承できます)。 public static final
として指定されているかどうかにかかわらず、すべての変数は暗黙的に定数です。指定されているかどうかにかかわらず、すべてのメンバーは暗黙的にpublic
name__です。一方、abstract
name__クラスは次のとおりです。
abstract
name__メソッドを持つ傾向があるため、完全に抽象的なものから完全に実装されたものまでどこにでもあります。宣言と定義の両方を含めることができ、宣言はabstract
name__としてマークされます。protected
name__、private
name__、またはプライベートパッケージ(未指定)に制限できます。interface
name__は実装クラス に がありますが、abstract
name__クラスはサブクラス に です。
実際の実装に代わる抽象クラスとインタフェースの違い。
Interface :これはキーワードであり、オブジェクトのテンプレートやブループリントを定義するために使用され、すべてのサブクラスが同じプロトタイプに従うように強制します。実装に関しては、すべてのサブクラスは自由に実装できます要件に応じた機能.
インターフェースを使うべき他のユースケースのいくつか。
Interface hereを介して行われる2つの外部オブジェクト間の通信(アプリケーションでのサードパーティの統合)は契約として機能します。
抽象クラス: 抽象、これはキーワードであり、このキーワードをクラスの前に使用すると抽象クラスになります。テンプレートを定義する必要がある場合、およびオブジェクトのデフォルト機能を使用する場合に主に使用されます。すべてのサブクラスが続き、このようにして冗長なコードを削除します。 抽象クラスを使用できるもう1つのユースケース 他のクラスがそのクラスのオブジェクトを直接インスタンス化できないなど、派生クラスのみ可能機能を使用してください。
抽象クラスの例:
public abstract class DesireCar
{
//It is an abstract method that defines the prototype.
public abstract void Color();
// It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.
// and hence no need to define this in all the sub classes in this way it saves the code duplicasy
public void Wheel() {
Console.WriteLine("Car has four wheel");
}
}
**Here is the sub classes:**
public class DesireCar1 : DesireCar
{
public override void Color()
{
Console.WriteLine("This is a red color Desire car");
}
}
public class DesireCar2 : DesireCar
{
public override void Color()
{
Console.WriteLine("This is a red white Desire car");
}
}
インタフェースの例:
public interface IShape
{
// Defines the prototype(template)
void Draw();
}
// All the sub classes follow the same template but implementation can be different.
public class Circle : IShape
{
public void Draw()
{
Console.WriteLine("This is a Circle");
}
}
public class Rectangle : IShape
{
public void Draw()
{
Console.WriteLine("This is a Rectangle");
}
}
単純だが明確な答えを出すには、コンテキストを設定するのが役立ちます。完全な実装を提供したくない場合は、両方を使用します。
その場合の主な違いは、インターフェースはまったく実装されていない(本体のないメソッドのみ)のに対し、抽象クラスは本体を持つメンバーとメソッドを持つこともできる、つまり部分的に実装できることです。
意味のある違いをもう1つ追加したいと思います。たとえば、数千行のコードを含むフレームワークがあります。それでは、メソッドenhanceUI()を使用してコード全体に新しい機能を追加したい場合は、インターフェイスではなく抽象クラスでそのメソッドを追加することをお勧めします。なぜなら、このメソッドをインタフェースに追加するのであれば、それをすべての実装クラスに実装する必要がありますが、抽象クラスに追加するのではありません。
定義上、インタフェースにはメソッドを実装することはできず、メンバ変数は初期化できません。
ただし、抽象クラスではメソッドを実装し、メンバ変数を初期化することができます。
契約の変更が予想される場合は抽象クラスを使用します。つまり、将来的に新しいメソッドを追加する必要があるかもしれないと言います。
このような状況で、あなたがインターフェースを使うことに決めた場合、そのインターフェースがインターフェースを含むように変更されたとき、あなたはあなたが新しいインターフェースDLLをダンプしたときにあなたのアプリケーションは壊れるでしょう。
詳しく読むには 抽象クラスとインタフェースの違いを見てください
抽象クラスは、オブジェクトを作成できないクラス、またはインスタンス化できないクラスです。抽象メソッドはクラスを抽象化します。 抽象クラスは、抽象クラスで宣言されているメソッドをオーバーライドするために継承する必要があります。 アクセス指定子に制限はありません。 抽象クラスは、それらの中にコンストラクタや他の具象(非abstarctメソッド)メソッドを持つことができますが、インタフェースは持つことができません。
インターフェースはメソッドの青写真/テンプレートです(例えば、紙の上の家が与えられると(インターフェースハウス)、さまざまな建築家がそれを構築するために彼らのアイデアを使います(家のインターフェースを実装する建築家のクラス)。これは抽象メソッド、デフォルトメソッド、静的メソッド、最終的な変数、およびネストされたクラスの集まりです。すべてのメンバはfinalまたはpublicになり、保護およびプライベートアクセス指定子は使用できません。オブジェクトの作成は許可されません。実装インターフェースを使用し、インターフェース内で宣言されている抽象メソッドをオーバーライドするためのクラスを作成する必要があるインターフェースは、疎結合の良い例です(動的多態性/動的バインディング)インターフェイスは多態性と抽象化を実装します。それは何をすべきかを指示しますが、行う方法は実装クラスによって定義されます。自動車会社があり、それがすべての自動車で同じであることを望みます。そのように製造するために会社は私が作っているでしょうこれらの機能とさまざまなクラスの車(Maruti Suzkhi、Maruti 800など)を持つインターフェース車は、これらの機能(機能)をオーバーライドします。
なぜ抽象クラスがあるのにインタフェースなのか? Javaはマルチレベルおよび階層継承しかサポートしていませんが、インタフェースの助けを借りて多重継承を実装できます。
多くのジュニア開発者は、インターフェイス、抽象クラスおよび具象クラスを同じことのわずかなバリエーションと考える間違いを犯し、純粋に技術的な理由でそれらのいずれかを選択します:多重継承が必要ですか?一般的なメソッドを配置する場所は必要ですか?具体的なクラス以外のものに悩む必要がありますか?これは間違っており、これらの質問に隠されていることが主な問題です"I"。自分でコードを書くとき、他の現在または将来の開発者が自分のコードに取り組んでいる、またはコードで作業していることを考えることはめったにありません。
インターフェイスと抽象クラスは、技術的な観点からは明らかに似ていますが、まったく異なる意味と目的を持っています。
インターフェース契約を定義するいくつかの実装があなたのために満たすこと。
抽象クラスデフォルトの動作を提供そのあなたの実装は再利用できます。
具体的なクラスは、非常に具体的な方法で実際の作業を行います。たとえば、ArrayList
は、メモリの連続領域を使用して、オブジェクトのリストをコンパクトな方法で格納します。これにより、高速なランダムアクセス、反復、インプレース変更が可能になりますが、挿入、削除、場合によっては追加でさえひどくなります。一方、LinkedList
は二重リンクノードを使用してオブジェクトのリストを格納します。これにより、代わりに高速の反復、インプレース変更、挿入/削除/追加が提供されますが、ランダムアクセスではひどいです。これら2つのタイプのリストは、異なるユースケースに合わせて最適化されており、どのように使用するかが非常に重要です。頻繁にやり取りしているリストからパフォーマンスを絞り出そうとする場合、およびリストの種類を選択するのはあなた次第であるため、インスタンス化するリストを慎重に選択する必要があります。
一方、リストの高レベルのユーザーは、実際にリストがどのように実装されるかを気にしません。これらの詳細から隔離する必要があります。 JavaがList
インターフェースを公開しなかったが、実際にはList
が実際に何であるかという具体的なLinkedList
クラスのみがあったと想像してみましょう。すべてのJava開発者は、実装の詳細に合わせてコードを調整します:ランダムアクセスを回避する、キャッシュを追加してアクセスを高速化する、またはArrayList
を独自に再実装しますが、他のすべてのコードとは互換性がありません実際にはList
のみで機能します。それはひどいことでしょう...しかし、Javaマスターが実際にほとんどの実際のユースケースでリンクリストがひどいことを認識し、利用可能なList
クラスのみの配列リストに切り替えることにしたと想像してください。これは、世界中のすべてのJavaプログラムのパフォーマンスに影響し、人々はそれについて満足しません。そして、主な犯人は、実装の詳細が利用可能であったことであり、開発者は、それらの詳細は信頼できる永続的な契約であると想定していました。そのため、実装の詳細を非表示にし、抽象コントラクトのみを定義することが重要です。これがインターフェイスの目的です。プログラマがコードを微調整して、将来の更新で変更される可能性のある内部の詳細に合わせることを誘惑するすべての内臓を公開することなく、メソッドが受け入れる入力の種類と出力が期待される種類を定義します。
抽象クラスは、インターフェイスと具象クラスの中間にあります。実装が一般的なコードまたは退屈なコードを共有するのに役立つはずです。たとえば、AbstractCollection
は、サイズが0に基づくisEmpty
の基本的な実装、反復および比較としてのcontains
、繰り返されるaddAll
としてのadd
などを提供します。これにより、実装はそれらを区別する重要な部分、つまり実際にデータを保存および取得する方法に集中できます。
インターフェースは、コードのさまざまな部分の間の結束力が低いゲートウェイです。これにより、内部で何かが変更されたときにすべてのライブラリユーザーに影響を与えることなく、ライブラリの存在と進化を可能にします。これはApplication Programming Interfaceと呼ばれ、Application Programming Classesではありません。小規模では、複数の開発者が、十分に文書化されたインターフェースを介して異なるモジュールを分離することにより、大規模プロジェクトで正常に共同作業することもできます。
抽象クラスは結束性が高いhelpers実装の詳細のある程度のレベルを想定して、インターフェースを実装するときに使用されます。あるいは、抽象クラスはSPI、サービスプロバイダーインターフェイスの定義に使用されます。
APIとSPIの違いは微妙ですが、重要です。APIの場合、焦点はses itであり、SPIの場合は焦点は、誰に実装 itです。
APIへのメソッドの追加は簡単で、APIの既存のユーザーはすべてコンパイルされます。すべてのサービスプロバイダー(具体的な実装)が新しいメソッドを実装する必要があるため、SPIにメソッドを追加するのは困難です。インターフェイスを使用してSPIを定義する場合、SPIコントラクトが変更されるたびに、プロバイダーは新しいバージョンをリリースする必要があります。代わりに抽象クラスが使用される場合、新しいメソッドは既存の抽象メソッドの観点から、または少なくとも古いバージョンのサービス実装をコンパイルおよび実行できる空のthrow not implemented exception
スタブとして定義できます。
Java 8はインターフェースのデフォルトのメソッドを導入しましたが、これによりインターフェースと抽象クラスの間の線がさらにぼやけますが、これは実装がコードを再利用できるようにするためではなく、 APIおよびSPIとして(または抽象クラスの代わりにSPIの定義に誤って使用されます)。
当然のことながら、逆の場合もよくあります:thingを使用する場合は、常に実際に必要な最も一般的なクラス/インターフェイスを使用してください。つまり、変数をArrayList theList = new ArrayList()
として宣言しないでください。実際にarrayリストであることに非常に強い依存関係があり、他のタイプのリストはそれをカットしません。代わりにList theList = new ArrayList
を使用します。リストであり、他の種類のコレクションではないという事実が実際に重要でない場合は、Collection theCollection = new ArrayList
を使用します。
php.net :の抽象クラスとインタフェースの簡単で効果的な説明
インターフェースはプロトコルのようなものです。オブジェクトの動作を指定するのではありません。それはあなたのコードがそのオブジェクトにどのように振る舞うように言うかを指定します。インターフェースは英語のようなものです。インターフェースを定義することは、コードがそのインターフェースを実装しているオブジェクトとどのように通信するかを定義します。
インターフェースは常に合意または約束です。クラスが「私はインターフェースYを実装する」と言うとき、それは「私はインターフェースYを持つすべてのオブジェクトが持つのと同じパブリックメソッドを持つことを約束する」と言っています。
一方、抽象クラスは、部分的に構築されたクラスのようなものです。それは記入することが空白のある文書に非常に似ています。それは英語を使っているかもしれませんが、それは文書のいくつかがすでに書かれているという事実ほど重要ではありません。
抽象クラスは他のオブジェクトの基盤です。クラスが「抽象クラスYを拡張する」と言うときは、「Yという名前のこの他のクラスで既に定義されているメソッドまたはプロパティを使用しています」という意味です。
だから、次のPHPを検討してください:
<?php class X implements Y { } // this is saying that "X" agrees to speak language "Y" with your code. class X extends Y { } // this is saying that "X" is going to complete the partial class "Y". ?>
他の人が使用するクラスを配布している場合は、そのクラスに特定のインターフェースを実装させることになります。インターフェースはあなたのクラスのためのパブリックメソッドの特定のセットを持つことへの同意です。
あなたが(あるいは他の誰かが)あなたがあなたの新しいクラスで使用したいいくつかのメソッドがすでに書かれているクラスを書いたなら、あなたはあなたのクラスに抽象クラスを拡張させるでしょう。
これらの概念は、混同しやすい一方で、特に異なり明確に区別されています。すべての意図と目的のために、あなたが自分のクラスのいずれかの唯一のユーザーであれば、あなたはインターフェースを実装する必要はありません。
インターフェースでは、すべてのメソッドは定義のみでなければならず、単一のメソッドを実装するべきではありません。
しかし抽象クラスには定義のみを持つ抽象メソッドがなければなりませんが、他のメソッドも実装を持つ抽象クラスに含めることができます...
通常抽象クラスは何かのコアに使用されますが、ペリフェラルを追加するために使用されるインターフェイスです。
あなたが車の基本型を作成したいときは抽象クラスを使うべきですがあなたが車の基本概念の一部ではない何らかの機能やプロパティを追加したいときはあなたはインターフェースを使うべきです、例えば "ToJSON()"関数を追加したいです。
interfaceは抽象クラスではなく幅広い抽象化を持っています。引数を渡すことでこれを見ることができます。
引数としてvehicleを使用する場合は、その派生型の1つを使用することができます(バスまたは同じカテゴリの自動車専用カテゴリ)。ただし、引数としてIMoveableインターフェイスを使用する場合はより多くの選択肢があります。
インタフェースは一般的に論理だけでシグネチャを持たないクラスです。抽象クラスは論理を持つものです。どちらも、すべてのメソッドをインタフェースとしてサポートするという契約は、子クラスで実装する必要がありますが、抽象メソッドでは抽象メソッドのみを実装する必要があります。いつインタフェースを使用し、いつ抽象化するのですか?なぜインターフェースを使うのですか?
class Circle {
protected $radius;
public function __construct($radius)
{
$this->radius = $radius
}
public function area()
{
return 3.14159 * pow(2,$this->radius); // simply pie.r2 (square);
}
}
//Our area calculator class would look like
class Areacalculator {
$protected $circle;
public function __construct(Circle $circle)
{
$this->circle = $circle;
}
public function areaCalculate()
{
return $circle->area(); //returns the circle area now
}
}
単純に
$areacalculator = new Areacalculator(new Circle(7));
数日後、四角形、四角形、四角形などの領域が必要になります。もしそうなら、コードを毎回変更して、インスタンスが正方形か、円形か、長方形かをチェックする必要がありますか?今OCPが言うのは、実装ではなくインタフェースへのコードです。 解決策は次のようになります。
Interface Shape {
public function area(); //Defining contract for the classes
}
Class Square implements Shape {
$protected length;
public function __construct($length) {
//settter for length like we did on circle class
}
public function area()
{
//return l square for area of square
}
Class Rectangle implements Shape {
$protected length;
$protected breath;
public function __construct($length,$breath) {
//settter for length, breath like we did on circle,square class
}
public function area()
{
//return l*b for area of rectangle
}
}
今面積計算機のために
class Areacalculator {
$protected $shape;
public function __construct(Shape $shape)
{
$this->shape = $shape;
}
public function areaCalculate()
{
return $shape->area(); //returns the circle area now
}
}
$areacalculator = new Areacalculator(new Square(1));
$areacalculator->areaCalculate();
$areacalculator = new Areacalculator(new Rectangle(1,2));
$areacalculator->;areaCalculate();
それより柔軟ではないですか?インターフェイスなしでコーディングする場合は、各形状の冗長コードのインスタンスを確認します。
今抽象を使用するとき?
Abstract Animal {
public function breathe(){
//all animals breathe inhaling o2 and exhaling co2
}
public function hungry() {
//every animals do feel hungry
}
abstract function communicate();
// different communication style some bark, some meow, human talks etc
}
抽象がそのクラスのインスタンスを必要としないとき、類似の論理を持つとき、契約を必要とするときに使われるべきです。
抽象クラスとそれの一般的な考え方は、これらの一般的な「設定」(ある種のテンプレート)を使用する他のクラス(単独では構築できない)によって拡張/実装されることです後でそれを拡張するオブジェクト。
抽象クラスは通常のメソッドセットと抽象メソッドを持ちます。拡張クラスは、抽象クラスによって拡張された後に未設定メソッドを含むことができます。抽象メソッドを設定するとき - それらは後でそれを拡張するクラスによって定義されます。
インタフェースは抽象クラスと同じプロパティを持ちますが、他のクラスに実装することができる(そして実装するための複数のインタフェースになることができる)抽象メソッドのみを含みます。変数抽象クラスとは異なり、カスタムの「通常の」メソッドを追加することはできません。
実用性の用語(Java)で、抽象クラスとインターフェイスの主な違いは抽象クラスは状態を保持できます。状態を保持する以外に、インターフェイスで休息操作を実現することもできます。
インターフェイスと抽象クラスの間には、構造上および構文上のさまざまな違いがあります。もう少し違いがあります
[1] シナリオベースの違い :
抽象クラスは、親クラスのオブジェクトを作成するようにユーザーを制限したい場合や、今後さらに抽象メソッドが追加される予定の場合に使用されます。
提供される抽象メソッドがこれ以上残っていないと確信できる場合は、インタフェースを使用する必要があります。その後、インターフェースのみが公開されます。
[2] 概念の違い :
YESで抽象クラスにし、NOでインタフェースにした場合、「将来、さらに抽象メソッドを提供する必要がありますか」。
(Java 1.7までは最も適切で有効)