Oop 面向对象问题:;如果对象是通过基本对象传输的,如何将对象转换为具体对象
我的演示代码如下:Oop 面向对象问题:;如果对象是通过基本对象传输的,如何将对象转换为具体对象,oop,interface,ooad,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 {
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的实例。我想访问“操作
”中的属性b
(ifSubB
)或PropertyA
(ifSubA
)。我是否违反了一些基本的OO规则?处理这种情况的最佳方法是什么(我不想用C#关键字作为
和是
来测试我转移的对象)。我现在完全糊涂了。非常感谢您提供的任何建议或帮助。您可以通过使用类型检查和强制转换(正如您已经看到的,C#中的as
和is
)轻松绕过技术限制,但这确实违反了基本的OO原则
问题是您已经定义了
Action
期望接收Base
作为参数,因此这是您应该依赖的唯一信息。如果类型为Base
的对象未公开需要公开的数据,则需要对其进行修改。例如,您可以将一个“Property”属性直接添加到base中,并使其成为某种泛型类型,或者添加到具有两个子项的base类型中,一个子项支持int
值,另一个子项支持string
值。如果你还可以考虑为什么<代码>动作< /代码>需要访问数据,并且可能将数据的使用委托给<代码> Base< /Cord>及其子代。 < P>可以通过使用类型检查和转换来轻松地绕过技术限制(<代码> A/<代码>和<代码> <代码> >,如您已经看到的,但这确实违反了OO的基本原则
问题是您已经定义了
Action
期望接收Base
作为参数,因此这是您应该依赖的唯一信息。如果类型为Base
的对象未公开需要公开的数据,则需要对其进行修改。例如,您可以将一个“Property”属性直接添加到base中,并使其成为某种泛型类型,或者添加到具有两个子项的base类型中,一个子项支持int
值,另一个子项支持string
值。如果你也可以考虑为什么<代码>动作< /代码>需要访问数据,并且可能将数据的用法委托给<代码> Base< /Cord>及其子代。 < P>我认为你做的很好,但是,你可能需要通过(Obj[SUB]){}}(Obj:Sub){}来找出OBJ的精确类名。< /P>
根据经验,创建类似void Action(Base obj)的函数的原因是处理obj,而不管它实际上是Base的哪个子类。因此,选择obj作为Base类型意味着您决定不在函数内部执行子类型特定的处理
我在上面的代码中看到,创建超类基类只是为了能够将SubA或SubB传递给Action,而在Action(Base obj)中,似乎您唯一的目的是根据它是SubA还是SubB来处理它。将SubA和SubB作为独立的类而不是继承Base更有意义。然后,您应该为每个SubA和SubB设置单独的操作重载:
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());
}
}
将调用适当的操作重载。让程序的逻辑决定实例化哪个类。尽量避免“嗅探”对象的实际类型。我认为您所做的很好,但是,您可能需要通过if(obj是SubA){}或者if(obj是SubB){}找到obj的确切类名 根据经验,创建类似void Action(Base obj)的函数的原因是处理obj,而不管它实际上是Base的哪个子类。因此,选择obj作为Base类型意味着您决定不在函数内部执行子类型特定的处理 我在上面的代码中看到,创建超类基类只是为了能够将SubA或SubB传递给Action,而在Action(Base obj)中,似乎您唯一的目的是根据它是SubA还是SubB来处理它。将SubA和SubB作为独立的类而不是继承Base更有意义。然后,您应该为每个SubA和SubB设置单独的操作重载:
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());
}
}
将调用适当的操作重载。让程序的逻辑决定实例化哪个类。尽可能避免“嗅探”对象的实际类型