事实上,C# 提供了以纯 OOP 方式获得相同行为而无需特殊词的可能性 - 它是私有接口。
至于问题什么是朋友的C#等价物?被标记为与本文重复,没有人提出真正好的实现 - 我将在这里给出这两个问题的答案。
主要思想来自这里:什么是私有接口?
比方说,我们需要一些类来管理另一个类的实例并在它们上调用一些特殊方法。我们不想给任何其他类调用这个方法的可能性。这与朋友 c++ 关键字在 c++ 世界中所做的完全相同。
我认为实际实践中的一个很好的例子可能是全状态机模式,其中一些控制器更新当前状态对象并在必要时切换到另一个状态对象。
你可以:
- 公开 Update() 方法的最简单和最糟糕的方法 - 希望每个人都能理解它为什么不好。
- 下一种方法是将其标记为内部。如果你把你的类放到另一个程序集中就足够了,但即便如此,该程序集中的每个类都可以调用每个内部方法。
- 使用私有/受保护的接口 - 我遵循这种方式。
控制器.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();
}
}
程序.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()");
}
}
最后是如何测试类控制器抛出继承的示例:
ControllerTest.cs
class ControllerTest: Controller
{
public ControllerTest()
{
IState testObj = new PlayerIdleState();
testObj.Update();
}
}
希望我涵盖所有情况,我的回答很有用。