实际上,C#提供了以纯OOP方式获得相同行为的可能性,而无需使用特殊词-它是私有接口。
就问题而言,朋友的C#等效项是什么?被标记为与本文重复,并且没有人提出很好的实现-我将在此处显示两个问题的答案。
主要思想是从这里获取的:什么是私有接口?
假设,我们需要一些可以管理另一个类的实例并对其调用一些特殊方法的类。我们不想给任何其他类调用此方法。朋友c ++关键字在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派生。
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();
}
}
希望我能涵盖所有情况,并且我的回答是有用的。