2016-10-21 10 views
1

私は、このインターフェイスを作成しました:オブジェクトを入力すると、Interfaceまたはクラスを使用する私に違いがありますか?

public interface IPhrase 
{ 
    int CategoryId { get; set; } 
    string PhraseId { get; set; } 
    string English { get; set; } 
    string Romaji { get; set; } 
    string Kana { get; set; } 
    string Kanji { get; set; } 
} 

と、このクラス:ここ

public class Phrase : IPhrase 
{ 
    public Phrase() 
    { 
    } 

    public int CategoryId { get; set; } 
    public string PhraseId { get; set; } 
    public string English { get; set; } 
    public string Romaji { get; set; } 
    public string Kana { get; set; } 
    public string Kanji { get; set; } 
} 

このコードは、データやフレーズに型キャスト、それを返します。

var phrases = db2.Query<Phrase>("SELECT * FROM Phrase", ans); 
var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans); 

私が知りたいのですがどうされますここでIPhraseを使用している場合に相違点がある場合はPhraseですか?また、この例では、私がIPhraseインターフェースを作成する際にどのような利点がありますか(もしあれば)。それはより読みやすいコードにつながりますか?

+4

あなたはいくつかの点で、ここでのインターフェイスを使用してIPhrase' 'の異なる実装を使用することを決定した場合、これはインターフェースが最初の場所に存在している理由の一つであり、あなたのメンテナンス時間を節約します。具体的なクラスを使用すると、この場合はメリットはありません – slawekwin

+0

利点は、前者が実際にコンパイルされて実行され、後者はコンパイル( 'T:class')または実行時に例外をスローするインタフェースをインスタンス化します。あなたの質問を詳述し、あなたの研究を分かち合いましょう。それは_なぜ "インターフェイスを使用するのですか?" _です。それから、それまでに何度も尋ねられたように検索してみてください。それが他のものなら、あなたの質問を答えることができるように[編集]します。 – CodeCaster

+0

私は、EF/Linq(どんなものでも)が問合せから戻るために具体的な型を作成する必要があるため、インタフェースで動作するかどうかはわかりません。この場合、それは不可能です。また、単純なエンティティ(独自の実際の振る舞いを持たない型)を扱う場合、intefaceには実質上の利点はほとんどありません。 – Igor

答えて

2

  1. 他のオブジェクト
  2. インタフェース

オブジェクト

あなたがAnimalオブジェクトを持っている場合は、Dogオブジェクトを継承することができますそれは動物であるからです。フレーズのオブジェクトの継承と思うと

:あなたは、そのオブジェクトの表現部と考えることができますインターフェイスを持つI am a ...._yourObject_...

インタフェース

。例えば、IWalkOnTwoLegsまたはICanSwimです。

だから、フレーズを考える:あなたがインターフェイスかを使用している場合、それが違いを生むだろう、あなたの質問に答えるために今I can do ...._yourInterface_..

まあ、それはこのケースではないだろうが、あなたのフレーズを拡張し、Question対象とStatementオブジェクトを作成し、例えば、それらがPhraseから継承する場合、あなたはすべてのフレーズを(返すことができる選択肢を持っています質問文)またはQuestionsまたはStatementsの唯一のフレーズ。

また、あなたがSpanishPhraseFrenchPhraseオブジェクトを拡張していることができますので、あなたのフレーズにIAmInFrenchIAmInSpanishを言っインターフェースを適用することができます。 質問、文、別の言語のいずれでも、すべてのフレーズを返すことができます。また、特定のフレーズのみを返すこともできます。

ここで、インターフェイスが最も有用であるとわかるのは、異なる種類の登録を1つにまとめるためです。それが違いを生むだろう

:あなたがインターフェイスを返すならば、あなたはしませんが、インターフェイス上ではなく、オブジェクトのプロパティがある場合、それは間違いなく違いを生むだろう

ですキャストを入力しない限り、そのプロパティに非常に簡単にアクセスできます。

例:

public class Phrase : IPhrase 
{ 
    public Phrase() 
    { 
    } 

    public int CategoryId { get; set; } 
    public string PhraseId { get; set; } 
    public string English { get; set; } 
} 

およびインターフェイス

public interface IPhrase 
    { 
     int CategoryId { get; set; } 
    } 

インターフェイスを返す場合は、プロパティ英語にアクセスすることはできません。

var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans); 
var eng = phrases[0].English; //**THIS WONT WORK** 
3

インターフェイスは、インターフェイスを実装するすべてのクラスがインターフェイスで定義されたメソッドとプロパティを実装することを保証するコントラクトです。これにより、インタフェースを使用して、インタフェースを実装する任意のクラスを受け入れるメソッド、リストなどを作成することができます。

public interface IExample 
{ 
    int GetInt(); 
} 

public void ProcessInt(IExample value) 
{ 
    var tempInt = value.GetInt(); 
    // Do processing here 
} 

これにより、インターフェイスIExampleを実装する任意の具象クラスをこのメソッドに渡すことができます。このメソッドは、渡された具象クラスにGetIntメソッドが実装されることを保証します。

+0

はい、これはなぜインターフェイスを使用するのか、とても素敵で簡単な説明ですが、質問との関係はわかりません。 – CodeCaster

+0

@CodeCasterインターフェイスがどのように使用されているかをより深く理解することで、OPが自分の質問の中心にあるような適切な状況でインターフェイスを使用する利点を理解できるようになります。 – Kevin

+0

ええ、それはひどい質問です、そして、このOPの621は、あなたが本当に不明な質問に答えるべきではないということです。 :) – CodeCaster

1

あなたの例のように、インタフェースと具体的なオブジェクトをローカルで使用することには違いはありません。主な違いは、APIとコンストラクタのパラメータのうち、具体的なクラスとインタフェースをインタフェースとして送信する場合です。インタフェースを使用することが好ましいため、デカップルとテスト容易性を実現できます。

あなたの質問には、インタフェースや具体的なオブジェクトをローカル変数として使用するかどうかにかかわらず、違いはありません。フィールドとプロパティは、より柔軟性を提供するインターフェイスとして宣言するのがよいことを忘れないでください。

インタフェースの代わりに具体的なオブジェクトをローカルで使用するときに考慮する必要がある最後のことは、いつかは、そのオブジェクトを提供するメソッドのシグネチャを変更して、そのオブジェクトを実装する別の種類のオブジェクトを返すことですインタフェース、およびその場合には次の例のように、(それはそう悪くはない、私がそれを注意しなければならなかった非常にまれにしか起こらない場合でも)あまりにもローカル変数を変更する必要があります。

interface IAnimal 
{ 
    void Run(); 
} 

class Cat : IAnimal 
{ 
    public void Run() 
    { 
     //... 
    } 
} 

class Dog : IAnimal 
{ 
    public void Run() 
    { 
     //... 
    } 
} 

もしあなたのコードでは、

Cat GetAnimal() 
{ 
    return new Cat(); 
} 

Cat myAnimal = GetAnimal(); //note that here it is expected a Cat 
myAnimal.Run(); 
を返すメソッドがあります。返される値は Catです。

は、その後、あなたがDogを返すようにGetAnimal署名を変更した場合、あなたのコードがにコンパイルするために変更する必要があります。

Dog myAnimal = GetAnimal(); //note that here it is expected a Cat 
myAnimal.Run(); 

しかし、あなたがインターフェイスを使用している場合、あなたのコードがする必要があります少ないチャンスがありますメソッドのシグネチャが変更されたときに変更される可能性があります。

IAnimal myAnimal = GetAnimal(); //this is working whether a Cat or a Dog is received. 
myAnimal.Run(); 

ただし、これは比較的まれに起こっています。愚かな猫のために申し訳ありません&犬の例!あなたは、物事に継承できるオブジェクトで

0

クラスはテンプレートですオブジェクトのために。本質的に青写真です。だから、光のために、オンとオフのボタンがあります。このメソッドを呼び出すと、その値をいくつかのコントローラーに送信して、そのコントローラーをオン/オフします。あなたがしなければならないことは、オン/オフのためのメソッドを呼び出すことであり、それは動作します。

インターフェイスは非常に似ています。ここではon/offメソッドが実装されていない可能性があります。実際にライトをオン/オフするためのコードを書く必要がありますが、on/offメソッドを記述する必要があります。そうしないと、そのインターフェイスにすることはできません。調光機能を備えた新しいタイプのライトがあるとします。インターフェイスを使用すると、異なるタイプのライトに対してこの新しい機能を実装できます。だから基本的には、あなたはそれがライトであるために(オン/オフ)このようなことをしなければならないと言っていますが、あなたはそれをどのように実装しても気にしません。インターフェースのいくつかの部分は、あなたのために実装されるかもしれませんが、あなたが実装しなければならない他の部分です。

インターフェイスはいつ意味がありますか?本質的に非常に似ているが、実装が少し異なる多くのオブジェクトがある状況。たとえば、多くの種類の図形があるとします。それぞれには領域があります。三角形の計算は、円の場合とは異なります。今では、構築する必要のある数百のシェイプがあり、シェイプの種類ごとに新しいオブジェクトを作成し続けることはないとしたら、インターフェイスを実装するだけです。これは、誰かに同様の方法で異なる実装を施して、形を作成する権限を与えます。

0

あなたの回答は、将来のクラスを使用する方法によって異なります。インタフェースは、子孫クラスがインタフェースのすべての定義を持つことを保証するための契約です。これは多態性を使いたいときに便利です。このようにして、インターフェイスクラスのオブジェクトのすべての共通仕様を定義できます。インターフェイスのもう1つの利点は、クラスが複数のインターフェイスから継承できることです。これはC#の他の種類のクラスでは許可されていません。次にコードの例を示します。あなたのために有用であると願っています:

public interface IShape 
{ 
    float Area { get; } 
    float circumference { get; } 
} 
public class Rectangle : IShape 
{ 
    private float l, h; 
    public Rectangle(float length, float height) { l = length; h = height; } 
    public float Area { get { return l * h; } } 
    public float circumference { get { return (l + h) * 2; } } 
} 
public class Circle : IShape 
{ 
    private float r; 
    public Circle(float radius) { r = radius; } 
    public float Area { get { return (float)Math.PI * r * r; } } 
    public float circumference { get { return (float)Math.PI * r * 2; } } 
} 

public class SomeClass 
{ 
    IShape[] shapes = new IShape[] // Can store all shapes regardless of its type 
    { 
     new Rectangle(10f, 20f), 
     new Rectangle(15f, 20f), 
     new Rectangle(11.6f, .8f), 

     new Circle(11f), 
     new Circle(4.7f) 
    }; 
    public void PrintAreas() 
    { 
     foreach (var sh in shapes) 
      Console.WriteLine(sh.Area); // prints area of shape regardless of its type 
    } 

    public void PrintCircumference(IShape shape) 
    { 
     Console.WriteLine(shape.circumference); // again its not important what is your shape, you cant use this function to print its cicumference 
    } 
} 
関連する問題