我必须在明天的工作中做一个关于抽象的简短介绍。我尝试了一些我的理解,但我不确定我是否做得正确。但它运作正常。
基本上我的TextBox
上有三个Form
和一个Button控件。我可以在前两个TextBox
控件中输入内容,按Button
控件,添加的结果显示在第三个TextBox
中。如果是数字,则显示总和。如果它是其他东西,它将把它作为一个字符串处理,然后连接它。
主-方法:
private void button1_Click(object sender, EventArgs e)
{
AbstractAddUp numberadding = new Numbers();
AbstractAddUp stringadding = new TextStrings();
//not really important, they are just used to satisfy parameters of int.Parse() method
int firstnumber;
int secondnumber;
//If values in textboxes are numbers...
if (int.TryParse(tbFirstOperand.Text, out firstnumber) && int.TryParse(tbSecondOperand.Text, out secondnumber))
{
object a = (object)(tbFirstOperand.Text);
object b = (object)(tbSecondOperand.Text);
tbResult.Text = numberadding.addValues(a, b).ToString();
}
//...otherwise, if they are of some other type, treat them as string
else
{
object a = (object)(tbFirstOperand.Text);
object b = (object)(tbSecondOperand.Text);
tbResult.Text = stringadding.addValues(a, b).ToString();
}
}
抽象类:
public abstract class AbstractAddUp
{
//abstract method that does the actual calculation or concatenation
protected abstract object DoOperation(object a, object b);
//public method to be called to initiate calculation/concatenation
public object addValues(object a, object b)
{
return DoOperation(a, b);
}
}
public class Numbers : AbstractAddUp
{
//overridden method for adding two numbers
protected override object DoOperation(object a, object b)
{
int firstnumber = int.Parse(a.ToString());
int secondnumber = int.Parse(b.ToString());
int result = firstnumber + secondnumber;
return (object)(result);
}
}
public class TextStrings : AbstractAddUp
{
//overridden method for concatenating two strings
protected override object DoOperation(object a, object b)
{
string strA = a.ToString();
string strB = b.ToString();
string result = strA + " " + strB;
return (object)(result);
}
}
答案 0 :(得分:3)
不,我认为这不是abstract class
的好用。类之间没有共享有用的实现,也没有真正共享的方法。您的示例非常简单,您应该使用更简单的代码。
//Check if value in textbox is a number or something else and add up
if (int.TryParse(tbFirstOperand.Text, out firstnumber) && int.TryParse(tbSecondOperand.Text, out secondnumber))
{
tbResult.Text = (firstnumber + secondnumber).ToString();
}
else
{
tbResult.Text = tbFirstOperand.Text + " " + tbSecondOperand.Text;
// or
tbResult.Text = string.Format("{0} {1}", tbFirstOperand.Text, tbSecondOperand.Text);
}
如果您可能希望以不同方式添加相似类型,例如也许字符串在中间添加了一个空格,中间可能带有逗号,那么让某些东西更复杂可能会有用。如果这种情况会受益于某种多态性,我认为一种好的方法是通用interface
或abstract class
(根据经验,如果abstract class
提供没有您要使用的实现或protected
属性,您可以使用interface
代替):
interface IAddUp<T>
{
T Add(T left, T right);
}
或者如果你让接口接受object
并让实现处理如何处理(但运行时失败的风险更高)
interface IAddUp
{
object Add(object left, object right);
}
class AddIntegers : IAddUp
{
public object Add(object left, object right)
{
return (int)left + (int)right;
}
}
答案 1 :(得分:3)
这不是抽象类的一个很好的例子,因为类不需要是抽象的代码才能工作。拥有一个抽象类的意义在于它不能自行运行,需要从具体实现中完成它才能使它完整。
这是一个抽象类的示例,其中类以不同的方式组合字符串,具体实现告诉如何组合它们:
public abstract class Combinator {
// the base class needs to ask for the separator to use
protected abstract string GetSeparator();
public string Combine(string value1, string value2) {
return value1 + GetSeparator() + value2;
}
}
public class SpaceCombinator : Combinator {
// the subclass needs to implement the abstract method for the code to compile
protected override string GetSeparator() {
return " ";
}
}
public class DashCombinator : Combinator {
public override string GetSeparator() {
return "-";
}
}
用法:
Combinator combinator;
combinator = new SpaceCombinator();
string name = combinator.Combine("John", "Doe");
combinator = new DashCombinator();
string phone = combinator.Combine("555", "524 855");
答案 2 :(得分:1)
我在想同样的话是蒂姆但不会使用if
。依赖类型会期望Add
类,如果它是AddStrings
或AddInts
则无关紧要。或者,基类可以从接口继承更进一步。
然后,您可以让工厂类决定返回哪种类型,从那时起您的应用程序不需要知道,也不关心。
public abstract class Add<T>
{
public abstract T AddSomething(T left, T right);
}
public class AddStrings : Add<string>
{
public override string AddSomething(string left, string right)
{
return left + right;
}
}
public class AddInts : Add<int>
{
public override int AddSomething(int left, int right)
{
return (left + right);
}
}