Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将超类传递给C#函数(带有Java序曲)_C#_Java_Oop_Inheritance_Polymorphism - Fatal编程技术网

将超类传递给C#函数(带有Java序曲)

将超类传递给C#函数(带有Java序曲),c#,java,oop,inheritance,polymorphism,C#,Java,Oop,Inheritance,Polymorphism,我已经有一段时间没有用Java OOP做任何事情了,所以我有点生疏了,希望得到一些澄清 在Java中,如果我没记错的话,可以声明一个超类并实例化一个子类;例如,超类myObject=new Subclass() 然后可以将myObject传递到接受超类参数的函数中,并使用引用访问任何超类属性/方法 这就是问题的症结所在——如果你想访问特定于子类的方法/变量,你可以直接用myObject(它被声明为一个超类)或者你需要先将它转换成一个子类类型吗 如果我们现在把这个问题推到C#上,同样的逻辑适用吗?

我已经有一段时间没有用Java OOP做任何事情了,所以我有点生疏了,希望得到一些澄清

在Java中,如果我没记错的话,可以声明一个超类并实例化一个子类;例如,
超类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的特定资源,我将不胜感激

获得所需功能的两种方法

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

第一,如果我有一个
集合
,它不知道
ArrayList
的作用,那么调用
ArrayList
的方法是不可能的

Collection collection = new ArrayList(); 
第二个例子:

ArrayList list = new ArrayList();  
通过上面的内容,我可以访问所有公共内容(从父类/接口共享)以及
ArrayList

这就是问题的症结所在——如果你想访问特定于子类的方法/变量,你可以直接用myObject(它被声明为一个超类)或者你需要先将它转换成一个子类类型吗

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

如果我们现在把这个问题推到C#上,同样的逻辑适用吗

是的,原理是一样的

至于你的例子:

bar.superOnly() //Should this work?

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

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

是的,多亏了多态性

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


如果要调用在子类上被重写的方法,可以通过超类变量调用它,子类的版本将被调用。

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

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

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


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

如果您需要访问特定于子类的方法,而不是基类中被重写的方法,该怎么办?@Drumalama,然后您需要子类的引用。编译器必须静态地了解方法;由于
subOnly
仅在
子类中声明,因此不能对super-classGotcha的变量调用它。根据Woot4Moo的建议,我可能最终会改变我的应用程序的架构,所以我不需要处理这个问题,因为它看起来有点混乱(例如,如果我需要再添加10个子类,就无法扩展)。@Drumalama,你到底想做什么?我不明白你为什么说它不可扩展;OOP是出了名的可扩展。。。也许你误解了什么?告诉我们更多关于您的场景,也许我们可以想出一个好的方法。实际上,这也可能不是最好的实现。也许某种字典会更好,因为不同的Profile对象之间唯一的差异是它们包含的属性。(它们都包含一些关键属性,如名称、ID等,但有些还有其他属性,如电子邮件、URL等)。我必须使用第一个选项,因为我试图将多种类型的对象传递到单个函数中。你是说,在传入“超类myClass”后,我访问子类特定属性的唯一方法是使用“(子类)myClass在我的函数中强制转换它吗?@dramallama是的。您需要检查对象的类型,或者认真重新考虑程序的架构。明白了。由于时间限制,这在混乱的临时调试版本中使用;最终,这一切都将变得更加优雅。:)非常感谢。这让我想起了一切。这就是当你在学术界花太多时间使用松散类型的Python而被宠坏时会发生的情况。:)关于参数,我强烈建议您阅读本文:
bar.subOverrided() // Will this call the superclass or subclass version? => the subclass