黑马程序员技术交流社区

标题: 覆写返回值是否相同问题[已解决] [打印本页]

作者: 小黑马    时间: 2012-8-31 13:34
标题: 覆写返回值是否相同问题[已解决]
本帖最后由 马小龙 于 2012-8-31 15:45 编辑

复习以前内容,在覆写这个知识点的返回值问题上产生疑问,
写了一个demo:



  1.     class Base {  
  2.       public Base newInstance() {  
  3.         return new Base();  
  4.       }  
  5.       public Base newInstance2() {  
  6.         return new Base();  
  7.       }  
  8.     }  
  9.     class Test extends Base {  
  10.       // 返回值不同  
  11.       public Test newInstance() {  
  12.         return new Test();  
  13.       }  
  14.       // 返回值相同  
  15.       public Base newInstance2() {  
  16.         return new Test();  
  17.       }  
  18.     }  
复制代码
发现如果用jdk1.4以前的版本编译会报错, 但是换成用jdk1.5以后的版本后就会编译成功,为什么?

作者: 袁艳超    时间: 2012-8-31 14:02
版本不一样,照理说不应该报错的,返回值不一样,相当于创建了一个新的方法,不叫覆盖,编译器出问题了吧
作者: 尤洋    时间: 2012-8-31 14:53
5.0版本之后支持 重写的的返回值为不同类型,但这个类型必须是所复写方法类型的子类。

以前上网时看到过关于这个的讨论,里面提到5.0新特性可以让重写的方法返回不同类型,
我自己试过几次都没成功,后来发现只有返回是子类类型才可以,其他类型的话都不行。

作者: 小黑马    时间: 2012-8-31 15:16
尤洋 发表于 2012-8-31 14:53
5.0版本之后支持 重写的的返回值为不同类型,但这个类型必须是所复写方法类型的子类。

以前上网时看到过关 ...

就是说也是属于覆盖范畴, 运行时新建子类对象的话,调用就是调用子类方法.
作者: 尤洋    时间: 2012-8-31 15:32
本帖最后由 尤洋 于 2012-8-31 15:44 编辑
马小龙 发表于 2012-8-31 15:16
就是说也是属于覆盖范畴, 运行时新建子类对象的话,调用就是调用子类方法. ...


属于覆盖,而不是新建了一个方法
验证方法很简单,改下代码试试就知道了
  1. public class YanZheng{

  2.         /**
  3.          * @param args
  4.          */
  5.         public static void main(String[] args) {
  6.                 // TODO Auto-generated method stub
  7.                 Test t=new Test();//初始化会输出fffffffff
  8.                 t.newInstance();//调用newInstance()方法,子类中具有父类的方法,如果不是复写的话,两个方法同名就会分不清到底该调用哪个newInstance()方法。
  9.         }
  10. }

  11. class Base {
  12.         
  13.   public Base newInstance() {  
  14.     return new Base();  
  15.   }  
  16.   public Base newInstance2() {  
  17.     return new Base();  
  18.   }  
  19. }  
  20. class Test extends Base {
  21.         Test()
  22.         {
  23.                 System.out.println("fffffffff");
  24.         }
  25.   // 返回值不同  
  26.   public Test newInstance() {  
  27.     return new Test();  
  28.   }  
  29.   // 返回值相同  
  30.   public Base newInstance2() {  
  31.     return new Test();  
  32.   }  
  33. }  
复制代码

作者: 黑马张涛    时间: 2012-8-31 15:58
我用反射试了一下,好像没有复写哦,只是调用不了了

import java.lang.reflect.Method;

class Base {  

  public Base newInstance() {  

    return new Base();  

  }  

  public Base newInstance2() {  

    return new Base();  

  }  
  
}  

class Test extends Base {  

  // 返回值不同  

public Test newInstance() {  

    return new Test();  

  }  

  // 返回值相同  

  public Base newInstance2() {  

    return new Test();  

  }  
  public static void main(String [] args)
  {
          Test t = new Test();
          Class clazz = t.getClass();
          Method [] me = clazz.getMethods();
          for(Method m:me)
          {
                  System.out.println(m.getName());
          }
  System.out.println(t.newInstance().getClass());
  }
  }
作者: 尤洋    时间: 2012-8-31 16:58
本帖最后由 尤洋 于 2012-8-31 17:22 编辑
黑马张涛 发表于 2012-8-31 15:58
我用反射试了一下,好像没有复写哦,只是调用不了了

import java.lang.reflect.Method;

你用反射得出两个相同方法名 并不能说明 父类方法没被复写。
只是由于返回值类型不同,复写前后的方法被getMethods()方法 判断为两个不同的Method对象。这两个对象再调用getName()方法得出两个函数名
而返回值类型相同时,复写前后的方法会被getMethods()认为是同一个Method对象。最后只有一个Method对象调用getName()方法得出一个函数名。

你的代码只能验证复写前后的两个方法 返回值 函数名 和参数列表是否相同,而不能说明是否被复写





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2