【问题标题】:OOP Issue:How to convert an object into concrete object if the object is transfered via base objectOOP问题:如果对象通过基础对象传输,如何将对象转换为具体对象
【发布时间】:2012-11-24 12:40:38
【问题描述】:

我的演示代码如下:


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

【问题讨论】:

    标签: oop interface ooad


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      根据经验,创建 void Action(Base obj) 之类的函数的原因是为了处理 obj,而不管它实际上可能是 Base 的哪个子类。因此,选择 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 重载。让程序的逻辑决定要实例化哪个类。尽可能避免“嗅探”对象的实际类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 2016-09-14
        • 2011-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多