java 子类重写父类的方法应注意的问题

若想实现一个合格重写方法,而不是重载,那么必须同时满足下面的要求!

A、重写规则之一:
    重写方法不能比被重写方法限制有更严格的访问级别。
(但是可以更广泛,比如父类方法是包访问权限,子类的重写方法是public访问权限。) 比如:Object类有个toString()方法,开始重写这个方法的时候我们总容易忘记public修饰符,编译器当然不会放过任何教训我们 的机会。出错的原因就是:没有加任何访问修饰符的方法具有包访问权限,包访问权限比public当然要严格了,所以编译器会报错的。

反正子类写public就肯定是没错的

B、重写规则之二:
   参数列表必须与被重写方法的相同。
重写有个孪生的弟弟叫重载,也就是后面要出场的。如果子类方法的参数与父类对应的方法不同,那么就是你认错人了,那是重载,不是重写。

C、重写规则之三:
   返回类型必须与被重写方法的返回类型相同。
父类方法A:void eat(){} 子类方法B:int eat(){} 两者虽然参数相同,可是返回类型不同,所以不是重写。
父类方法A:int eat(){} 子类方法B:long eat(){} 返回类型虽然兼容父类,但是不同就是不同,所以不是重写。

D、重写规则之四:
   重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常。但是可以抛出更少,更有限或者不抛出异常。

 1 import java.io.*;
 2 public class Test {
 3   public static void main (String[] args) {
 4    Animal h = new Horse();
 5    try {
 6      h.eat();
 7    }
 8    catch (Exception e) {
 9    }
10  }
11 }
12
13 class Animal {
14   public void eat() throws Exception{
15    System.out.println ("Animal is eating.");
16    throw new Exception();
17   }
18 }
19
20 class Horse extends Animal{
21    public void eat() throws IOException{
22     System.out.println ("Horse is eating.");
23     throw new IOException();
24   }
25 }

这个例子中,父类抛出了检查异常Exception,子类抛出的IOException是Exception的子类,也即是比被重写的方法抛出了更有限的异常,这是可以的。如果反过来,父类抛出IOException,子类抛出更为宽泛的Exception,那么不会通过编译的。
注意:这种限制只是针对检查异常,至于运行时异常RuntimeException及其子类不再这个限制之中。

E、重写规则之五:
   不能重写被标识为final的方法。

F、重写规则之六:
  如果一个方法不能被继承,则不能重写它。

比较典型的就是父类的private方法。下例会产生一个有趣的现象。

 1 public class Test {
 2   public static void main (String[] args) {
 3    //Animal h = new Horse();
 4    Horse h = new Horse();
 5     h.eat();
 6    }
 7 }
 8
 9 class Animal {
10    private void eat(){
11     System.out.println ("Animal is eating.");
12     }
13  }
14
15 class Horse extends Animal{
16    public void eat(){
17      System.out.println ("Horse is eating.");
18    }
19 }

这段代码是能通过编译的。表面上看来违反了第六条规则,但实际上那是一点巧合。Animal类的eat()方法不能被继承,因此Horse类中的 eat()方法是一个全新的方法,不是重写也不是重载,只是一个只属于Horse类的全新的方法!这点让很多人迷惑了,但是也不是那么难以理解。
main()方法如果是这样:
Animal h = new Horse();
//Horse h = new Horse();
h.eat();
编译器会报错,为什么呢?Horse类的eat()方法是public的啊!应该可以调用啊!请牢记,多态只看父类引用的方法,而不看子类对象的方法!

曾志伟的见解如下

多态只看父类引用的方法,而不堪子类对象的方法!什么意思呢?Animal h=new Horse();这个体现了多态,但是h.eat()只会调用子类重写父类的那个方法,而该demo中因为父类的方法是private的,所以子类无法重写这个方法,也就是子类那个eat()是子类自己新创建的方法,跟父类没有半点关系,所以这时候Animal h=new Horse();会报错

时间: 2024-10-24 02:28:21

java 子类重写父类的方法应注意的问题的相关文章

子类重写父类的方法应注意的问题

若想实现一个合格重写方法,而不是重载,那么必须同时满足下面的要求! 重写规则之一:重写方法不能比被重写方法限制有更严格的访问级别. (但是可以更广泛,比如父类方法是包访问权限,子类的重写方法是public访问权限.) 比如:Object类有个toString()方法,开始重写这个方法的时候我们总容易忘记public修饰符,编译器当然不会放过任何教训我们 的机会.出错的原因就是:没有加任何访问修饰符的方法具有包访问权限,包访问权限比public当然要严格了,所以编译器会报错的. 重写规则之二: 参

java子类重写父类方法测试

父类 package com.yjm.Tes; public abstract class Ts { protected void Test(String str ,String s){ System.out.println("ts..."); } } 子类 package com.yjm.Tes; public class Test extends Ts { protected final void Test(String str, String s) { System.out.pr

java中子类重写父类方法的思想本质

java语言中,在子类中定义与父类同返同名同参的方法将会出现"重写(覆写)",子类将屏蔽父类的相同方法,调用子类的方法将不会调用到父类的该方法. 许多初学者也许会被"覆写"一词迷惑,以为覆盖掉了父类的方法,其实这两种方法是同时独立存在的,只是子父类调用该方法的入口不一样,彼此互不干扰. 1 /* 2 需求:设计一个简单的java程序,证明子类重写父类方法的过程 3 思路: 1.创建父类对象,通过父类对象调用该方法 4 2.创建子类对象,通过父类对象调用该方法 5 3

关于继承时子类重写父类方法和覆盖父类变量的若干问题

假设,子类重载父类的方法,并将子类的成员覆盖. 创建子类对象实例,将其上转型成父类. 例子1 public class Parent { public void init() { System.out.println("1 init parent"); this.demo(); } public void demo() { System.out.println("2 demo parent"); } } public class Son extends Parent

解决重写父类的方法且不会影响继承的子类的问题

基类的方法被所有继承的子类继承,是不应该被修改的,如果继承的子类重写了基类的方法,那么,再从这个子类派生出子类的话,这个派生的子类接口已经破坏掉了统一的接口. 但有时候,我们需要一个子类能扩展基类的方法,但又不想破坏这个统一的接口,这时候,哥就来教你既能扩展功能,又能保证接口的统一性:) 首先做几个实验验证: 提供的源码如下: A类  B类  C类  (B类继承于A类,C类继承于B类) // // A.h // Super // // Copyright (c) 2014年 Y.X. All r

子类重载父类的方法“parent:方法名”

在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法重写. 子类中重载父类的方法就是在子类中覆盖从父类中继承过来的方法,父类中的方法被子类继承过来不就可以直接使用吗?为什么还要重载呢?因为有一些情况我们必须要覆盖的.例如,有一个“鸟”类,在这个类中定义了鸟的通用方法“飞翔”.将“鸵鸟”类作为它的子类,就会将“飞翔”的方法继承过来,但只要一调用“鸵鸟”

Java拾遗(一):浅析Java子类和父类的实例化顺序 及 陷阱

本文主要介绍Java里经常使用的子类和父类的变量实例化顺序及陷阱,并结合一个Android实例来探讨此问题.日后编程中应尽量避免此陷阱. 首先看以下一段代码: 定义一个虚类Server.java package org.yanzi.test1; public abstract class Server { private static final int DEFAULT_PORT = 900; public Server() { // TODO Auto-generated constructo

python子类调用父类的方法

python子类调用父类的方法 python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法.如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找. 继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函数的. 子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题 如果子类和父类都有构造函数,子类其实是重写了父类的构造函数

重写父类的方法及经典类和新式类的区别

1.父类重写的实例展示 (继承才有父类) # coding=utf-8 class Zll(): # def smile(self): #      print('哈哈哈') #      return 'aa' pass class Dcg(): def smile(self): print('啊啊啊啊啊') class Lw(): def smile(self): print('嘿嘿嘿') class Xz(Zll,Dcg,Lw):   #继承多个父类依次找父类是否有该方法,有就调用. de