実際、C#は、特別な言葉なしで純粋なOOPの方法で同じ動作を実現する可能性を提供します。これはプライベートインターフェイスです。
質問までC#の友達と同等のものは何ですか?この記事の重複としてマークされ、誰も本当に良い実現を提案していません-私はここで両方の質問に対する答えを示します。
ここからの主なアイデアは、プライベートインターフェイスとは何ですか。
たとえば、別のクラスのインスタンスを管理し、それらに対して特別なメソッドを呼び出すことができるクラスが必要だとします。このメソッドを他のクラスに呼び出す可能性を与えたくありません。これは、c ++の世界でfriend c ++キーワードが行うこととまったく同じです。
実際の良い例は、一部のコントローラーが現在の状態オブジェクトを更新し、必要に応じて別の状態オブジェクトに切り替える、フルステートマシンパターンであると考えられます。
あなたは出来る:
- Update()メソッドを公開する最も簡単で最悪の方法-なぜそれが悪いのか理解してほしい。
- 次の方法は、内部としてマークすることです。クラスを別のアセンブリに配置すれば十分ですが、そのアセンブリの各クラスが各内部メソッドを呼び出すこともできます。
- プライベート/保護されたインターフェースを使用します-そして私はこの方法に従いました。
Controller.cs
public class Controller
{
private interface IState
{
void Update();
}
public class StateBase : IState
{
void IState.Update() { }
}
public Controller()
{
//it's only way call Update is to cast obj to IState
IState obj = new StateBase();
obj.Update();
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
//it's impossible to write Controller.IState p = new Controller.StateBase();
//Controller.IState is hidden
var p = new Controller.StateBase();
//p.Update(); //is not accessible
}
}
さて、継承についてはどうですか?
明示的なインターフェイスメンバーの実装は仮想として宣言できず、IStateを保護対象としてマークしてコントローラーから派生する可能性もあるので、説明されている手法を使用する必要があります。
Controller.cs
public class Controller
{
protected interface IState
{
void Update();
}
public class StateBase : IState
{
void IState.Update() { OnUpdate(); }
protected virtual void OnUpdate()
{
Console.WriteLine("StateBase.OnUpdate()");
}
}
public Controller()
{
IState obj = new PlayerIdleState();
obj.Update();
}
}
PlayerIdleState.cs
public class PlayerIdleState: Controller.StateBase
{
protected override void OnUpdate()
{
base.OnUpdate();
Console.WriteLine("PlayerIdleState.OnUpdate()");
}
}
そして最後に、クラスControllerスロー継承をテストする方法の例:
ControllerTest.cs
class ControllerTest: Controller
{
public ControllerTest()
{
IState testObj = new PlayerIdleState();
testObj.Update();
}
}
私がすべてのケースをカバーし、私の答えが役に立てば幸いです。