Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.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
Java 在子类中已重写的超类中使用方法,具体取决于调用它的对象的类型_Java_Eclipse_Inheritance_Polymorphism - Fatal编程技术网

Java 在子类中已重写的超类中使用方法,具体取决于调用它的对象的类型

Java 在子类中已重写的超类中使用方法,具体取决于调用它的对象的类型,java,eclipse,inheritance,polymorphism,Java,Eclipse,Inheritance,Polymorphism,我正在寻找一种方法来调用(重写)方法的不同定义,具体取决于调用该方法的对象的类型。当我详细阐述下面的观点时,这应该更有意义 我有两个类,定义如下: public class SuperClass{ public method1(){ if (objects are of type SuperClass and not SubClass){ //pseudocode method2(); }

我正在寻找一种方法来调用(重写)方法的不同定义,具体取决于调用该方法的对象的类型。当我详细阐述下面的观点时,这应该更有意义

我有两个类,定义如下:

public class SuperClass{

     public method1(){
           if (objects are of type SuperClass and not SubClass){ //pseudocode
                method2();
           }
           //do some more stuff
     }

     public method2(){
         //do stuff
     }
}

public class SubClass extends SuperClass{

     @Override
     public method1(){
          method2();
          super.method1();
     }

     @Override
     public method2(){
         //do stuff
     }

}
在这两个类中,我使用了3个对象,分别称它们为
dog
cat
、和
bird
dog
cat
都是
超类
类型的对象,而
bird
子类
类型的对象

您注意到,所有对象在代码中都遵循相同的基本过程,它们的
method1()
在执行任何其他操作之前调用
method2()
。它们之间的区别显然是
子类
重写
method2()
bird
具有不同的
method2()

目前,我的代码正在按照我想要的方式工作,但我正在寻找一个更优雅的解决方案(如果有的话)。你可以从我上面的代码中看到我是如何绕过手头的问题的:在
超类
中,我基本上检查对象的类型是否为
超类
。在我的实际程序中,伪代码行看起来更像这样(仍然是“伪代码”):

在调用
method1()的原始定义之前,
bird
调用它自己对
method2()的定义。基本上,这两个类都处理自己的
method2()
本地定义

我对更优雅的方法的想法如下:从
子类
中完全删除
method1()
的重写定义,并能够在适当的时间(即当我处理的对象是
bird
时)从
超类
中调用
method2()
的重写定义

基本上,我在编写时就尝试了上述方法,但是
bird
对象最终使用了
方法2()
的定义,该定义位于
超类中,而不是
子类中的定义


可以这样做吗?如果可以,如何做?

您可以使用
instanceOf()
方法检查对象是否是另一个类的实例。然而,对于所有的超类,这也将返回true


然而,我相信您所说的是,如果子类过度使用某个方法,您希望子类调用它们自己的方法版本。这将自动发生,因为不应在超类方法中检查类型。不使用发布的
toString()
方法,也不使用
instanceof
方法。让多态性为你工作

多态性的整个概念是,您可以对超类类型调用一个方法,对象的行为将与其实际类型相同。标准教科书示例如下所示:

Cat cat = new Cat();
Animal animal = cat;
animal.speak();

假设您没有看到
animal=cat
作业。你只有一只
动物
。你不知道它是猫、狗还是大象,你只知道它有说话的方法。由于多态性,对象将根据其实际类型进行操作,而无需检查内部类型。

继承和重写完全按照您的要求工作,而无需检查实例是超级类还是子类

就这样

public class SuperClass{
     public method1(){
         method2(); // Note that you don't need any instance check here.
         //do some more stuff
     }

     public method2(){
         SOP("Super method2");
     }
}

public class SubClass extends SuperClass{
     @Override
     public method2(){ // Note that you don't have to override method1
         SOP("SUB method2")
     }
}
在这种情况下,如果使用超类对象调用,
method1()
,它将调用超类的
method2()
,并打印
Super method2


如果使用子类对象调用,
method1()
,它将调用子类的
method2()
,并打印
submethod2

,以便根据调用方法的对象的类型调用方法的不同定义,这就是它的工作方式

如果找到合适的函数,则调用该函数。在本上下文中,“合适”是指以下情况之一: •找到了完全匹配的。 •进行了一次微不足道的转换。 •进行了整体提升。 •存在到所需参数类型的标准转换。 •存在到所需参数类型的用户定义转换(转换运算符或构造函数)。 •发现由省略号表示的参数

编译器为每个参数创建一组候选函数。候选函数是一种函数,在该函数中,处于该位置的实际参数可以转换为形式参数的类型。 为每个参数构建一组“最佳匹配函数”,所选函数是所有集合的交集。如果交集包含多个函数,则重载不明确并生成错误。对于至少一个参数,最终选择的函数始终比组中的所有其他函数更匹配。如果不是这样(如果没有明确的赢家),函数调用将生成一个错误

public class SuperClass{
     public method1(){
         method2(); // Note that you don't need any instance check here.
         //do some more stuff
     }

     public method2(){
         SOP("Super method2");
     }
}

public class SubClass extends SuperClass{
     @Override
     public method2(){ // Note that you don't have to override method1
         SOP("SUB method2")
     }
}