因此,我有下面的方法,它是abstract
类的一部分,该类基本上是二维字符数组。我打算有几个行为略有不同的子类,它们知道如何以不同的方式填充自身。
该方法应该在该数组中插入一个字符串。为避免溢出错误,我需要检查阵列中是否有空间。检查这是否足够的空间就足够简单了,但这就是问题的开始。
如果没有足够的空间,我希望每个子类定义如何处理该行为。 (例如,某些子类将仅从头开始,其他子类将不执行任何操作并停止插入字符,其他子类将擦除第一行,将所有内容向上移动,并将其写在底部的新空白行上,其他子类将放弃并使程序崩溃等)
请参阅以下代码中的注释。我想我想对实现进行override
编码,但是有什么方法可以覆盖else分支,还是必须将整个方法移到子类中?
(IsEnoughRoom
是类中的私有(private)方法。)
internal void InsertString(string stringToInsert, int xStart, int yStart)
{
char[] charsToInsert = stringToInsert.ToCharArray();
int currentXPosition = xStart;
int currentYPosition = yStart;
// For each character in the array of charsToInsert,
for (int i = 0; i < charsToInsert.Length; i++)
{
// Check if there is enough room...
if(isEnoughRoom(xStart, yStart, charsToInsert))
{
SetCharAt(currentXPosition, currentYPosition, charsToInsert[i]);
if (currentXPosition < xSize - 1)
{
currentXPosition++;
}
else
{
currentXPosition = 0;
currentYPosition++;
}
}
else
{
//TODO: What do we do if there isn't enough room?
}
}
最佳答案
还有一种可能的替代方法,其中抽象类的方法是virtual
,它可以返回一个枚举值以确定结果是什么,然后由调用者执行其余操作。整个调用者可以是派生类。
让我们看看这个解决方案的实际效果:
public enum CharInsertionResult
{
Success,
NoRoom
}
public abstract class CharInserter
{
internal virtual CharInsertionResult InsertString(string stringToInsert, int xStart, int yStart)
{
char[] charsToInsert = stringToInsert.ToCharArray();
int currentXPosition = xStart;
int currentYPosition = yStart;
// For each character in the array of charsToInsert,
for (int i = 0; i < charsToInsert.Length; i++)
{
// Check if there is enough room...
if(isEnoughRoom(xStart, yStart, charsToInsert))
{
SetCharAt(currentXPosition, currentYPosition, charsToInsert[i]);
if (currentXPosition < xSize - 1)
{
currentXPosition++;
}
else
{
currentXPosition = 0;
currentYPosition++;
}
return CharInsertionResult.Success
}
else
{
return CharInsertionResult.NoRoom;
}
}
}
}
现在派生类可以重写抽象类的实现,以解决
CharInsertionResult.NoRoom
的问题:public class SpecializedCharInserter : CharInserter
{
internal override CharInsertionResult InsertString(string stringToInsert, int xStart, int yStart)
{
CharInsertionResult result = base.InsertString(stringToInsert, xStart, yStart);
switch(result)
{
case CharInsertionResult.NoRoom:
// Do stuff here to handle this scenario
break;
default:
return result;
}
}
}
恕我直言,我认为这是一个很好的设计,因为如果您不想处理
NoRoom
方案,则不需要覆盖方法,否则,您就可以在派生类中进行扩展。