超类引用子类对象,显示与子类对象的子类引用相同的行为

java中的以下代码,当在elipse上运行时,即使我们替换也会提供相同的输出

superclass s=new sub(); 

用,

 sub s= new sub(); 

请注意,我们已经重写了方法。

输出是:

 changed supermethod in sub class num is sub class 5 

码:

 public class superclass { int num=2; public static void main(String str[]){ superclass s=new sub(); //HERE: nothing changes if we write, sub s=new sub(); s.supermethod(); s.method(); } void supermethod(){ System.out.println("supermethod as in superclass"); } void method(){ System.out.println("num in superclass "+num); } } class sub extends superclass{ int num=5; void method(){ System.out.println("num is sub class "+num); } void supermethod(){ System.out.println("changed supermethod in sub class"); } } 

请指出,以这两种方式创建子类对象有什么不同。 访问方法和变量会有什么不同吗? (我们的java老师说,访问方法和变量在两种情况下都会有所不同)

此外,静态方法会发生什么,例如main。 我知道它是可inheritance的,但有人可以强调它在子类中的行为吗?

在Java中,所有非静态方法都是“虚拟”,这意味着它们基于底层对象的运行时类型,而不是指向该对象的引用类型。 因此,在对象的声明中使用哪种类型无关紧要,行为将是相同的。

声明的作用是,在编译时可见的方法。 如果SubClass有一个SuperClass没有的方法(我们称之为subMethod() ),你将对象构造为

 SuperClass s = new SubClass(); 

然后,您将只能调用SuperClass上可用的SuperClass 。 也就是说,尝试调用s.subMethod()会给你一个编译时错误。 但是,正如您所发现的,如果SuperClass存在方法,但SubClass重写了它,那么它将是将被执行的重写方法。

另一方面,静态方法不是虚拟的。 运行下面的代码

 public class StaticTest { public static void main(String[] args) { SuperClass s = new SubClass(); s.method(); // bad idea - calling static method via an object reference } public static class SuperClass { public static void method() { System.out.println("SuperMethod"); } } public static class SubClass extends SuperClass { public static void method() { System.out.println("SubMethod"); } } } 

打印出“SuperMethod”。 但是,您应该很少关注static方法是非虚拟的,因为您不应该像上面那样通过对象引用来调用它们。 你应该通过类名称来调用它们:

 SuperClass.method(); 

我在这里通过一些修改重写你的代码。 请看一下这些变化。

 public class superclass { int num=2; public static void main(String str[]){ superclass s=new sub(); //HERE: nothing changes if we write, sub s=new sub(); s.supermethod(); s.method(); } ... ... //This method is not overridden. void methodInSuper(){ System.out.prinln("method not overridden."); } } class sub extends superclass{ int num=5; ... ... //This is only in subclass. void methodInSub(){ System.out.println("method only in subclass."); } } 

现在,当您创建这样的对象时:

 superclass s1=new sub(); 

然后你可以调用所有重写的方法

 s1.supermethod(); s1.method(); 

在这种情况下,将调用子类的方法。
你也可以调用那些没有被覆盖的超类方法

 s1.methodInsuper(); 

但是如果你尝试访问仅在子类中定义的方法,比如

 s1.methodInsub(); 

那么这将是一个编译时错误。

它是becoz s1属于Superclass类型。
如果你仍然想在子类中调用该方法,那么你需要将s1类型转换为子类

 Sub s = (Sub) s1; 

之后,您可以调用子类的方法。
如果你创建一个像这样的对象

 Sub s2 = new Sub(); 

然后,您可以访问子类或超类中定义的任何方法。

早期创建的对象基本上用于实现“运行时多变量”。
希望你得到你的答案。

你正在创建sub的sub并将它分配给super的reference.if你不要1)第一种情况: –

 superclass s=new sub(); s.supermethod(); s.method(); 

在上面的情况下,将调用sub的方法但是这两个方法也应该存在于超类中(如果不存在则编译时错误)

2)第二种情况: –

 sub s=new sub(); s.supermethod(); s.method(); 

在这也是sub的方法,这些方法可能存在也可能不存在超级。

让我们举一个例子:sup是A类对象的引用变量。 和sub是B类对象的引用变量。 我们假设B扩展了A. 所以如果我们写“sup = sub;” 或“sup = new B();” 这个语句使我们能够获得两个类之间共同的属性。 即:Binheritance的属性…我们使用这个技巧来检查Binheritance的属性并进行了更改。