我希望有一个名为IProblem
的问题的界面。有两种方法:Solve()和CheckArguments()。 Problem
类将实现CheckArguments()函数,因为它对于所有问题都是相同的。但是我有不同类型的问题,如EasyProblem
和HardProblem
,它们具有不同的Solve()方法实现,但CheckArguments()方法总是相同的,我总是想使用基类问题( )的实施。
我想有正确的修饰符,我对哪个类/接口中定义的方法有点困惑。更不用说我也有这两个功能的测试项目。
答案 0 :(得分:3)
我不确定你的问题是“使用什么”,但我建议使用一个接口和一个抽象类:
public interface IProblem {
void Solve();
void CheckArguments();
}
public abstract class Problem : IProblem {
public abstract void Solve();
public void CheckArguments() {
...
}
}
public class EasyProblem : Problem
{
public override void Solve()
{
....
}
}
这样,check参数在基类中实现,所有派生类都实现了IProblem,每个派生类都必须实现Solve。
如果省略界面并且只支持派生自Problem
的类,您将确保给定的类不能提供它自己的CheckArguments()
实现。强>
public abstract class Problem {
public abstract void Solve();
public void CheckArguments() {
...
}
}
public class EasyProblem : Problem
{
public override void Solve()
{
....
}
}
...
static Main(string[] args)
{
List<Problem> problemsToSolve = ...
foreach(var problem in problemsToSolve)
{
problem.CheckArguments();
problem.Solve();
}
}
答案 1 :(得分:3)
您可以尝试以下内容:
public interface ISupportArguments
{
bool CheckArguments();
}
public abstract class AbstractProblem : ISupportArguments
{
public bool CheckArguments() {
return true;
}
public abstract void SolveProblem();
}
所以你的每一课都来自AbstractProblem
并覆盖它自己的
SolveProblem(..)
答案 2 :(得分:0)
Matten很好地展示了班级结构
关于访问修饰符:我建议采用防御方法,以便您使用解决问题的限制性最强的访问修饰符。之后限制较少比限制更容易,因为您可能需要向代码的某些用户解释为什么他们不能再使用它。
因此对于类型(接口和类):如果在其他程序集中不需要它们,而是将它们定义为内部。如果要从测试项目中访问类型,可以使用InternalsVisibleTo属性从特定程序集访问它们。将属性添加到包含类型的程序集中,并将测试程序集的名称(以及强命名程序集的一些其他数据)作为参数提供。
这同样适用于会员。您还可以考虑实现接口explicitly,这样只有在通过接口访问类时才能访问这些方法。