6

C++ では、次のことができます。

class base_class
{
public:
    virtual void do_something() = 0;
};

class derived_class : public base_class
{
private:
    virtual void do_something()
    {
        std::cout << "do_something() called";
    }
};

はメソッドをderived_classオーバーライドしてにします。その結果、このメソッドを呼び出す唯一の方法は次のようになります。do_something()private

base_class *object = new derived_class();
object->do_something();

オブジェクトを type として宣言するderived_classと、プライベートであるためメソッドを呼び出すことはできません。

derived_class *object = new derived_class();
object->do_something(); 
// --> error C2248: '::derived_class::do_something' : cannot access private member declared in class '::derived_class'  

インターフェイスとして使用される抽象クラスを作成すると、フィールドを具象型として誤って宣言する人が誰もいないことを確認できますが、常にインターフェイス クラスを使用するため、これは非常に優れていると思います。

publicC# / .NET では一般的に、メソッドをオーバーライドするときに からへのアクセスを狭めることはできないprivateため、ここで同様の効果を達成する方法はありますか?

4

4 に答える 4

15

インターフェイスを明示的に実装すると、少なくとも宣言でインターフェイス型を使用するようになります。

interface IMyInterface
{
    void MyMethod();
}

class MyImplementation : IMyInterface
{
    void IMyInterface.MyMethod()
    {
    }
}

インスタンスを にキャストした後にのみ MyMethod が表示されますIMyInterface。宣言がインターフェイス型を使用する場合、その後の使用でキャストは必要ありません。

明示的なインターフェイスの実装に関する MSDN ページ(Luke に感謝します。数秒節約できます^^)

IMyInterface instance = new MyImplementation();
instance.MyMethod();

MyImplementation instance2 = new MyImplementation();
instance2.MyMethod();  // Won't compile with an explicit implementation
((IMyInterface)instance2).MyMethod();
于 2010-05-05T11:23:57.433 に答える
4

明示的なインターフェイスの実装を使用して、.Net の世界でもこれを行うことができます。

例として、 をBindingList<T>実装IBindingListしていますが、メソッドを表示するにはキャストする必要がありますIBindingList

于 2010-05-05T11:19:22.817 に答える
2

としてマークすることで、メソッドの可用性を下げることnewできます。

MSDN の CA2222の例: 継承されたメンバーの可視性を低下させないでください:

using System;
namespace UsageLibrary
{
    public class ABaseType
    {
        public void BasePublicMethod(int argument1) {}
    }
    public class ADerivedType:ABaseType
    {
        // Violates rule: DoNotDecreaseInheritedMemberVisibility.
        // The compiler returns an error if this is overridden instead of new.
        private new void BasePublicMethod(int argument1){}       
    }
}

これは、学術的な演習として非常に興味深いものです。コードが を呼び出せないことに本当に依存している場合BasePublicMethodADerivedTypeそれは疑わしい設計の警告サインです。

于 2010-05-05T11:18:57.897 に答える
0

この戦略が実装された場合の問題は、メソッドが完全に非公開ではないことです。への参照をアップキャストした場合base_class、メソッドはパブリックになります。derived_class::do_something()これは仮想メソッドであるため、プライベートとしてマークされていてもユーザー コードは実行されます。

于 2010-05-05T11:19:32.733 に答える