OOP问题:如果通过基础对象传输对象,如何将对象转换为具体对象

时间:2012-12-06 13:15:03

标签: oop interface ooad

我的演示代码如下:


class Base
{

}

class SubA:Base
{
     private int propertyA;
     public int  PropertyA     
     {
          get{return propertyA}
      }
}

class SubB:Base
{
     private string propertyB;
     public string PropertyB     
     {
          get{return propertyB}
      }
}

class Program
{
     public void Action(Base obj)
     {
         //here i wanna use PropertyB if the ture obj is an instance of SubB.
         // use PropertyA if the true obj is an instance of SubA
     }
}

我转移到功能的真实对象" Action"是SubB或SubA的实例。我想访问" PropertyB"中的SubB(如果PropertyA)或SubA(如果Action)。我是否违反了一些基本的OO规则?处理这种情况的最佳方法是什么(我不想使用C#关键字AsIs来测试我转移的obj)。我现在完全糊涂了。非常感谢任何建议或帮助。

2 个答案:

答案 0 :(得分:2)

您可以通过在C#中使用类型检查和强制转换(asis来轻松绕过技术限制,正如您已经看到的那样),但这确实违反了基本的OO原则。

问题在于您已定义Action期望接收Base作为参数,因此这是您应该依赖的唯一信息。如果类型为Base的对象未公开您需要公开的数据,则需要对其进行修改。例如,您可以将“Property”属性直接添加到base,并将其设置为某种泛型类型,或者添加到具有两个子项的基本类型中,一个支持int值,另一个string值。如果你也可以考虑为什么 Action需要访问数据,并且可能会将该数据的使用权委托给Base及其子代,这可能会有所帮助。

答案 1 :(得分:1)

我认为你所做的很好,但你可能需要找出obj的精确类名if if(obj是SubA){} else if(obj is SubB){}。

根据经验,创建像void Action(Base obj)这样的函数的原因是处理obj而不管它实际上是什么子类。因此,通过选择obj为Base类型意味着您决定不在函数内部执行特定于子类型的处理。

我在上面的代码中看到,超类Base只能创建为能够将SubA或SubB传递给Action,而在Action(Base obj)中,似乎你的唯一目的是根据它来处理它无论是SubA还是SubB。将SubA和SubB作为不继承Base的单独类更有意义。然后,对于SubA和SubB中的每一个,您应该有一个单独的Action重载:

class Program
{
     public void Action(SubA obj)
     {
         // process exactly as SubA
     }

     public void Action(SubB obj)
     {
         // process exactly as SubB
     }
}

程序中的其他代码应该构造成知道正在处理哪个SubA或SubB。您可以根据用户输入或条件实例化SubA或SubB。例如:

protected void saveButton_onClick(Object sender, EventArgs e)
{
    if (User.IsInRole("Administrator"))
    {
         Action(new SubA());
    }
    else
    {
         Action(new SubB());
    }
}

将调用适当的Action重载。让程序的逻辑决定实例化哪个类。避免需要尽可能“嗅探”对象的实际类型。