[解決済み] なぜprotectedインターフェイスのメンバを持つことができないのですか?
質問
インターフェイスで protected-access のメンバを宣言することに対する反論は? 例えばこれは無効です。
public interface IOrange
{
public OrangePeel Peel { get; }
protected OrangePips Seeds { get; }
}
この例では、インターフェイス
IOrange
は、実装者が
少なくとも
を提供します。
OrangePips
インスタンスを提供します。もし実装者が望むなら、スコープを完全な
public
:
public class NavelOrange : IOrange
{
public OrangePeel Peel { get { return new OrangePeel(); } }
protected OrangePips Seeds { get { return null; } }
}
public class ValenciaOrange : IOrange
{
public OrangePeel Peel { get { return new OrangePeel(); } }
public OrangePips Seeds { get { return new OrangePips(6); } }
}
の意図は
protected
メンバのサポート契約を提供することです。
継承者
(サブクラス) などのサポート契約を提供することです。
public class SpecialNavelOrange : NavelOrange
{
...
// Having a seed value is useful to me.
OrangePips seeds = this.Seeds;
...
}
(確かに、これは
struct
s)
のケースはあまり見当たりません。
private
または
internal
修飾子の両方をサポートしていますが
public
と
protected
修飾子は完全に合理的であると思われます。
の有用性を説明してみようと思います。
protected
のメンバーについて
interface
から切り離すことで
interface
を完全に分離することです。
新しいC#のキーワードを想像してみましょう。
support
という、継承者の契約を強制するためのキーワードを用意し、以下のように宣言するようにします。
public support IOrangeSupport
{
OrangePips Seeds { get; }
}
これにより、クラスを契約して、継承者にprotectedなメンバを提供することができるようになります。
public class NavelOrange : IOrange, IOrangeSupport
{
public OrangePeel Peel { get { return new OrangePeel(); } }
protected OrangePips Seeds { get { return null; } }
}
これは特に有用ではありません。なぜなら、クラスはすでに
protected
メンバを提供することによって、この契約をすでに暗示しているからです。
でも、それならこうもできる。
public interface IOrange : IOrangeSupport
{
...
}
これにより
IOrangeSupport
を実装する全てのクラスに
IOrange
を実装し、特定の
protected
メンバを提供することを要求する - これは現在私たちができることではありません。
どのように解決するのですか?
インターフェイスは公開メンバーのみを持ち、実装の詳細を持たないという点は、誰もが打ち明けたことだと思います。あなたが探しているものは 抽象クラス .
public interface IOrange
{
OrangePeel Peel { get; }
}
public abstract class OrangeBase : IOrange
{
protected OrangeBase() {}
protected abstract OrangePips Seeds { get; }
public abstract OrangePeel Peel { get; }
}
public class NavelOrange : OrangeBase
{
public override OrangePeel Peel { get { return new OrangePeel(); } }
protected override OrangePips Seeds { get { return null; } }
}
public class ValenciaOrange : OrangeBase
{
public override OrangePeel Peel { get { return new OrangePeel(); } }
protected override OrangePips Seeds { get { return new OrangePips(6); } }
}
編集:Ornamentクラスから派生したPlasticOrangeがあったとして、それはIOrangeしか実装できず、Seedsのprotectedメソッドは実装できないという主張は妥当でしょう。それはそれでいいのです。インターフェイスの定義は、呼び出し側とオブジェクトの間の契約であって、クラスとそのサブクラスの間の契約ではありません。抽象クラスは、この概念に限りなく近い。そして、それはそれでいいのです。あなたが本質的に提案しているのは、あるベースクラスから別のベースクラスへ、ビルドを壊さずにサブクラスを切り替えることができる、言語の別の構成です。私にとっては、これは意味を成しません。
クラスのサブクラスを作成する場合、そのサブクラスはベースクラスの特殊化です。それは、ベース クラスの任意の保護されたメンバーを完全に認識する必要があります。しかし、突然ベースクラスを切り替えたい場合、サブクラスが他のIOrangeで動作しなければならないのは意味がありません。
正しい質問だと思いますが、コーナーケースのようで、正直なところ何のメリットも見出せません。
関連
-
[解決済み】C#で四捨五入する方法
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] インターフェースと抽象クラスの違いは何ですか?
-
[解決済み] IDisposable インターフェースの正しい使用法
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] インターフェースと抽象クラス(一般的なOO)
-
[解決済み] パブリック、プライベート、プロテクトの違いは何ですか?
-
[解決済み] C#では、public、private、protected、アクセス修飾子がないことの違いは何ですか?
-
[解決済み] Javaインターフェースでスタティックメソッドを定義できないのはなぜですか?
-
[解決済み】「インターフェースに合わせたプログラム」とはどういう意味ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
[解決済み】C#はJavaのcharAt()と同等?)
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】2年前のMSDateを把握する【クローズド
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み】パラメータ付きRedirectToAction
-
[解決済み】プロセスが実行されているかどうかを知るには?
-
[解決済み] インターフェイスで保護する