A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 庄星睿 中级黑马   /  2012-7-15 01:11  /  1949 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 庄星睿 于 2012-7-15 09:11 编辑

对于方法重重写,视频里已经讲的很清楚了,但有一点忽略了,就是返回值类型可以不同,但子类方法的返回值必须小于等于父类,我总结了一下:
即子类包含和父类中同名的方法,被称为方法覆盖 override
方法的重写要遵循“两同两小一大”规则,“两同”指方法名相同,形参列表相同;“两小”指子类方法的返回值类型比
父类方法的返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;“一大”指的是
子类方法的访问权限应该比父类方法的访问权限更大或相等。
注意: 静态只能覆盖静态,如果父类方法具有 private 访问权限,则该方法对其子类是隐藏的,如果子类中定义了一个与父类private方法具有相同的方法名,相同的参数列表,相同的返回值类型的方法,依然不是重写,只是在子类中重新定义了一个新的方法。
写了一个例子(基本上都覆盖到了):

class FuException extends RuntimeException
{
}
class ZiException extends FuException
{
}
class Fu
{
            Fu method() throws FuException //返回值类型为Fu
          {
                  System.out.println("Fu...");
                  return new Fu();
  
           }
}
class  Zi extends Fu
{
          protected Zi method() throws ZiException  //这里只能抛父异常或者父类的子异常,返回值类型为Zi
         {
             System.out.println("zi....");
             return new Zi();
         }
         public static void main(String[] args)
         {
             Fu f=new Zi();
             f.method();
             System.out.println("Hello World!");
          }
}

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

7 个回复

倒序浏览
一大指的是
子类方法的访问权限应该比父类方法的访问权限更大或相等。
注意: 静态只能覆盖静态,如果父类方法具有 private 访问权限,则该方法对其子类是隐藏的,如果子类中定义了一个与父类private方法具有相同的方法名,相同的参数列表,相同的返回值类型的方法,依然不是重写,只是在子类中重新定义了一个新的方法。
我也贴段代码
  1. public class Test
  2. {
  3.     public static void main(String[] args)
  4.     {
  5.         Parent parent = new Child();
  6.         parent.outPut();
  7.     }
  8. }

  9. class Parent
  10. {
  11.     public void outPut() throws NullPointerException
  12.     {
  13.         System.out.println("parent outPut");
  14.     }
  15. }

  16. class Child extends Parent
  17. {
  18.     public void outPut() throws Exception
  19.     {
  20.         System.out.println("child outPut");
  21.     }
  22. }
复制代码
编译出错:Child 中的 output() 无法覆盖Parent 中的 output(); 被覆盖的方法不抛出 java.lang.Exception

子类中的方法的访问级别不能低于父类中该方法的访问级别,为何呢?假如没有这个限制, 如果Child类的 outPut() 方法的访问级别为 private ,将会与 java 的多态机制发生冲突。Parent parent = new Child(); parent.outPut(); 这里Java 编译器会认为以上是合法的,但在运行时,根据动态绑定规则,Java 虚拟机会调用 parent 变量所引用的 Child 实例的 outPut()  方法,而 Child 的 outPut() 方法为 private,Java虚拟机无法访问。为了避免这样的矛盾,Java 虚拟机不允许子类方法缩小父类中被覆盖方法的访问权限。
回复 使用道具 举报
对于方法重重写,视频里已经讲的很清楚了,但有一点忽略了,就是返回值类型可以不同//看完楼主写的这句话,我怎么觉得,楼主没有理解全面呢,方法重写,就是方法名相同,形参列表相同,但返回值类型也必须相同的吖,如果一个返回void,一个返回String,那就没有对方法进行重写吖。


下面是我对重写和覆盖的总结:
重载重写都需要方法名相同; 重载要求参数列表不同; 重写要求参数列表、返回值都相同所以你说的重写的“两同两小一大”规则应该为”三同一小一大”规则即,方法名。形参列表。返回值都必须相同,而,重载对返回值类型是没什么特殊要求的,只求方法名相同,形参列表不同而已。
希望楼主好好查查资料,谨慎发帖呀,以免让对这个问题本就模棱两可的同学更迷糊吖。。。。
回复 使用道具 举报
苑占丽 发表于 2012-7-15 11:52
对于方法重重写,视频里已经讲的很清楚了,但有一点忽略了,就是返回值类型可以不同//看完楼主写的这句话, ...

呵呵,重写首先存在子父类中,子类方法的返回值类型小于等于父类方法的返回值即可,is a的关系,你那个void和String 没有任何关系的,否则我写的代码也不会运行了
回复 使用道具 举报
庄星睿 发表于 2012-7-15 17:24
呵呵,重写首先存在子父类中,子类方法的返回值类型小于等于父类方法的返回值即可,is a的关系,你那个vo ...

你的代码是能够运行的吖,但这个和重写有关吗?
如果你写的那个method方法是重写的话,那子类中的method的方法权限很明显是小于父类的method方法权限的吖,而如果是重写的话,子类重写方法的权限应该大于等于父类的吖,这一句也是你说的吖,我也赞同,那你说这个到底是重写呢还是重载吖,还是什么都不是呢?还是由于用到了多态而产生的一种特殊情况的重写呢?
回复 使用道具 举报
苑占丽 发表于 2012-7-15 17:43
你的代码是能够运行的吖,但这个和重写有关吗?
如果你写的那个method方法是重写的话,那子类中的method ...

我这里没说重载,是重写就是覆盖

protected权限要大于默认访问权限的
默认什么都不加,是包访问权限,但如果加了protected,权限就提升了,不同包中的子类也可以访问
回复 使用道具 举报
庄星睿 发表于 2012-7-15 18:14
我这里没说重载,是重写就是覆盖

protected权限要大于默认访问权限的

反正要是重写,返回值类型就必须一样,这是一定的,对于权限问题我没有异议。
回复 使用道具 举报
苑占丽 发表于 2012-7-15 20:07
反正要是重写,返回值类型就必须一样,这是一定的,对于权限问题我没有异议。 ...

那时1.4以前了
5.0以后新增了协变返回类型(covariant return)
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马