インターフェイスにインスタンス変数や実装を含めることはできません。しかし、私たちはプロパティを持つことができます。プロパティはメソッドを取得して設定するだけではありませんか?そして、getメソッドとsetメソッドは、変数を取得して設定する方法だけではありませんか?これは浮気ではありませんか?私が覚えている限り、C++とJavaはこれを許可していません。C#でのインターフェイスの実装については、それほど「純粋」ではないものがあるようです。
4 に答える
プロパティはメソッドを取得して設定するだけではありませんか?
はい、そうです。それらはメソッドです。動作。その動作がどのように実装されるかについての実装の詳細ではありません。これがプロパティとフィールドの違いです。そのため、インターフェイスでプロパティが許可されます。
そして、getメソッドとsetメソッドは、変数を取得して設定する方法だけではありませんか?
いいえ、それらはメソッドです。それらはあなたが望むように実装することができます。それらは単純なフィールドを介して実装される場合がありますが、そうではない場合があります。DateTime.Now
(どのフィールドが読めると思いますか?)
私が覚えている限り、C++とJavaはこれを許可していません。
Javaでは確かにgetterメソッドとsetterメソッドをインターフェースに配置できます...
インターフェイスに表示されるのは具体的なプロパティではなく、プロパティのシグネチャ(プロパティ名、リターンタイプのアクセス修飾子、getとsetのどちらがあるかなど)の定義にすぎません。このインターフェースを実装するクラスで。
インターフェイスでは、これはget and setメソッドではなく、実際のメソッドでもありません。これは、このインターフェイスを実装するクラスでgetandsetメソッドがどのように見えるかを定義するだけです。
これは微妙に聞こえるかもしれませんが、そうではありません。それは大きな違いです。
抽象クラス内では、次のようなものを参照していることを知っています
public abstract void Required(int a, string b);
抽象メソッドとして。これは私が推測するセマンティクスであり、ここで一般的に受け入れられている使用法を変更するものは何もありませんが、(インターフェイス定義のように)実際には、これから派生するクラス内のメソッドの署名の仕様と要件にすぎません。抽象クラス。
プロパティは単なるゲッターとセッターです。はい(monodis
またはildasm
実行可能ファイルを使用してこれを確認し、それらが単なるメソッドであることを確認できます。
したがって、インターフェイスのプロパティは単なる抽象関数です。バッキングフィールドがあるかどうかは関係ありません。バッキングフィールド(そのプロパティに属する変数)は、基本的に、プロパティ自体とは何の関係もありません。
つまり、プロパティはメモリを必要とせず、データではありません。バッキングフィールドは必要かもしれませんが、プロパティ自体はデータではありません。
プロパティは2つのメソッドであり、単一の名前としてのパッケージです。インターフェイスでプロパティを定義することにより(Name
たとえば)、実際には2つの別々のメソッド(get_Name
およびset_Name
)を定義しています。メソッド(get
およびset
アクセサー)は必要に応じて定義できます。通常、フィールドの値を返すか設定しますが、これは必須ではありません。
JavaまたはC++でも、2つの別々のメソッドを定義することで同じことができます(getName
たとえばsetName
)。
インターフェイスのプロパティは、C#で自動実装されたプロパティのように見えるかもしれませんが、実際には異なります。このようなインターフェースを定義する場合:
interface IPerson
{
string Name { get; set; }
}
インターフェイス実装者に、という名前の読み取り/書き込みプロパティを作成するように強制していますName
が、クラスで同じことを行う場合は次のようになります。
class Person
{
public string Name { get; set; }
}
コンパイラは、文字列値を保持するためのバッキングフィールドを自動的に作成し、その文字列フィールドとの間で読み取り/書き込みを行う2つのメソッドを定義します。