Java编程关于子类重写父类方法问题的理解

  

子类重新实现父类的方法称重写;重写时可以修改访问权限修饰符和返回值,方法名和参数类型及个数都不可以修改;仅当返回值为类类型时,重写的方法才可以修改返回值类型,且必须是父类方法返回值的子类;要么就不修改,与父类返回值类型相同。那么,该如何理解呢?为什么要是父类返回值类型的子类?

  

提出问题:子类必须重写父类所有方法吗?

  

Java,子类不是必须重写父类所有方法的,分为以下两种情况:

  

父类方法为抽象方法时,子类必须重写(实现)所有父类的抽象方法;
  父类方法为普通方法时,子类可以重写父类方法,也可以不重写。
  举例如下:

        抽象类一个{   公共空间(){   }   公共抽象空白b ();   }   公共B类扩展了{//必须重写b方法,一方法可以不重写   公共空间b () {   }   }      

还是先看示例,详见下文。

  

包人类中定义了三个类,类,学生类和TestMain类,其学生类中是人类的子类。代码分别如下:

  

人类的代码如下:

        包人;   公共类人{   字符串名称;   int年龄;//测试:重写   公众人物覆盖(){   人每=new ();   per.name=傲酢?   回报;   }   }      

学生类重写了父类的覆盖()方法,代码如下:

        包人;   公开课学生扩展人{   字符串stuNumber;   int分数;//测试:重写   公开学生覆盖(){   学生stu=new ();   stu.name="李";   返回斯图;   }   }      

TestMain类的代码如下:

        包人;   公开课TestMain {   公共静态void main (String [] args) {   学生stu=new ();   人每=new ();   每=stu.overRide ();   System.out.println (per.name);   每=per.overRide ();   System.out.println (per.name);   }      

输出结果为:

        李   李      

有没有人跟我一样,第一反应输出应该为“李刘”呢,怎么两个都是“李”?

  

仔细分析一下,看下面的几张内存图就明白了。

  

第1,第2条语句分别创建一个子类对象和一个父类对象,其中,斯图指向子类对象,每指向父类对象。如下面图1所示:

  

癑ava编程关于子类重写父类方法问题的理解"

  

接着执行第3条语句:每=stu.overRide ();。

  

斯图先调用覆盖(),方法体里创建了一个子类对象,并让临时变量stu指向该对象,其存储位置就是以C为首地址的内存块;

  

然后把该对象的变量名称赋值为“李”;最后返回斯图的值并赋给每一个,也就是说,虽然每是父类对象引用,但最后指向了覆盖()里创建的子类对象,这里以蓝色箭头表示,原先指向的以B为首地址的父类对象这时没有引用指向它,这里把红色箭头变为虚线表示。此时访问每一个的名字,显然是“李”。内存结构见图2:

  

癑ava编程关于子类重写父类方法问题的理解"

  

再接着要执行/=per.overRide();,调用覆盖()方法;

  

由于子类重写了父类的覆盖()方法,虽然每为父类对象引用,此时父类的该方法被覆盖,所以此时要调用子类的方法;执行过程同上,每不再指向以C为首地址的子类对象,改为指向新创建的子类对象,以D为首地址,如图3所示。

  

同上面一样的道理,此时访问每个的名字仍然为“李”,因为父类的覆盖()两次压根都没有被调用到。

  

癑ava编程关于子类重写父类方法问题的理解"

  

修改一下TestMain,如下所示:

        包人;   公开课TestMain {   公共静态void main (String [] args) {   学生stu=new ();   人每=new ();   人per2=每;///=stu.overRide ();   System.out.println (per.name);   每=per.overRide ();   System.out.println (per.name);   per2=per2.overRide ();//System.out.println (per2.name);//}      

此时定义了一个父类对象引用per2,并让它与每指向同一个对象,最后两行,由per2调用覆盖()方法,很显然要调用父类的方法,所以方法体中创建的也是父类的对象,再把结果返回给per2,此时per2指向新创建的父类对象,该父类对象的名字就为“刘”了。

Java编程关于子类重写父类方法问题的理解