2

自从我对 Java OOP 做任何事情以来已经有一段时间了,所以我有点生疏,想要澄清一下。

在 Java 中,如果我没记错的话,可以声明一个超类并实例化一个子类;例如,Superclass myObject = new Subclass()

然后可以将 myObject 传递给接受超类参数的函数,并使用引用访问任何超类属性/方法。

这就是事情变得模糊的地方 - 如果您想访问特定于子类的方法/变量,您可以直接使用 myObject (它被声明为超类)执行此操作,还是需要先将其转换为子类类型?

如果我们现在将其转至 C#,是否适用相同的逻辑?我在尝试复制这种行为时遇到了一些奇怪的问题。我正在查看的具体用例是:

//These are just declarations for ease-of-reading
Superclass bar = new Subclass();
public static void doSomething(Superclass foo) {...}

//Logic
doSomething(bar);
bar.superOnly() //Should this work?
bar.subOnly() //Should this work?
bar.subOverrided() //Will this call the superclass or subclass version?

我也在教程中查找这些内容,但大多数示例似乎都是简单的“Subclass myObject = new Subclass()”实例,输出微不足道。到目前为止,我发现的任何内容都没有涵盖函数参数的模糊世界。

如果有人可以帮助我,或者将我指向涵盖 C# 中的函数参数和 OO 的特定资源,我将不胜感激!

4

4 回答 4

3

获得所需功能的两种方法。

1) 将对象转换为子类
2) 从一开始就将对象实例化为子类。

对于第一,如果我Collection不知道 anArrayList是做什么的,那么就不可能调用ArrayList.

Collection collection = new ArrayList(); 

第二个例子:

ArrayList list = new ArrayList();  

以上使我可以访问公共的所有内容(从父类/接口共享)以及在ArrayList

于 2012-05-25T19:30:25.133 回答
3

这就是事情变得模糊的地方 - 如果您想访问特定于子类的方法/变量,您可以直接使用 myObject (它被声明为超类)执行此操作,还是需要先将其转换为子类类型?

是的,这就是多态性的用途。在派生类中重写的基类的虚拟方法将始终被调用,即使您通过基类型的引用调用该方法也是如此。

如果我们现在将其转至 C#,是否适用相同的逻辑?

是的,原理是一样的

至于你的例子:

bar.superOnly() //Should this work?

是的

bar.subOnly() //Should this work?

不,因为编译器不知道这个方法

bar.subOverrided() // Will this call the superclass or subclass version? => the subclass

是的,由于多态性

于 2012-05-25T19:32:34.307 回答
2

如果要调用仅在子类上声明的方法,则必须将变量强制转换为子类或从子类类型的变量开始。

如果要调用在子类上被覆盖的方法,可以通过超类变量调用,会调用子类的版本。

于 2012-05-25T19:34:18.830 回答
2

在 C# 和 Java 中,规则非常一致。

声明一个具有特定类型的变量,该类型指示您可以使用的接口。声明的类型是变量之前的类型名称。只有定义为声明类型的一部分的方法才能使用(无需强制转换)。

相反,定义可以是声明类型或声明类型的任何子类或实现。该定义不会改变通过该变量提供给您的接口,它定义了该变量的实现。对象变量的定义是分配给它的值(右侧),通常使用new.

变量的声明类型只能通过转换为其他类型来更改,这可能会也可能不会成功(编译器不一定知道您的转换是否有效)。

于 2012-05-25T19:37:31.467 回答