`
7090
  • 浏览: 273401 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

(转)子类重新父类方法的限制

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

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

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

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

D、重写规则之四:重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常。但是可以抛出更少,更有限或者不抛出异常。
import java.io.*;
public class Test {
public static void main (String[] args) {
Animal h = new Horse();
try {
h.eat();  
}
catch (Exception e) {
}
}
}

class Animal {
public void eat() throws Exception{
System.out.println ("Animal is eating.");
throw new Exception();
}
}

class Horse extends Animal{
public void eat() throws IOException{
System.out.println ("Horse is eating.");
throw new IOException();
}
}
这个例子中,父类抛出了检查异常Exception,子类抛出的IOException是Exception的子类,也即是比被重写的方法抛出了 更有限的异常,这是可以的。如果反过来,父类抛出IOException,子类抛出更为宽泛的Exception,那么不会通过编译的。
注意:这种限制只是针对检查异常,至于运行时异常RuntimeException及其子类不再这个限制之中。

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

F、重写规则之六:如果一个方法不能被继承,则不能重写它。
比较典型的就是父类的private方法。下例会产生一个有趣的现象。
public class Test {
public static void main (String[] args) {
//Animal h = new Horse();
Horse h = new Horse();
h.eat();
}
}

class Animal {
private void eat(){
System.out.println ("Animal is eating.");
}
}

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


上述原则是以java语言的特性讲的,对于c++语言,原则同样使用。。。


分享到:
评论

相关推荐

    java三大特性说明

    方法的重写:发生在父子类之间,子类方法对父类的方法有新的实现方法,但两个方法定义部分完全一致. 继承的目的: 实现代码的复用.理顺类型对象之间的结构关系. 构建一个父类的时候,要求他的子类与父类必须有理论...

    java面试题

    如果父类的方法是private类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。 至于Overloaded的方法是否可以改变返回值的类型这个问题,要看你倒底想问什么呢?这个题目很模糊。如果几个...

    php 三大特点:封装,继承,多态

    概念:父类引用子类实例,由于子类里面对父类的方法进行重写,父类引用在调用该方法的时候表现出的不同状态 条件: 1必须发生在集成下 2必须重写父类方法 3父类引用调用方法 如果一个方法需要一个父类参数,可以给一...

    C++ 面向对象示例

    【C++ 语言】面向对象 ( 继承 | 重写 | 子类调用父类方法 | 静态多态 | 动态多态 | 虚函数 | 纯虚函数 ) : https://hanshuliang.blog.csdn.net/article/details/99690475 【C++ 语言】面向对象 ( 模板编程 | 函数...

    Java基础知识总结(总共六章)

    许多重继承:一个子类只能继承一个父类,不能继承多个父类; 在java 中允许多层继承,在继承中子类不能访问父类中的私有操作,而 只能继承全部的公有操作,对于私有内容不能直接访问,但是可以通过 其他途径访问 在...

    编程技能训练与等级考试辅导:继承、super关键字.pptx

    在子类中覆盖父类的方法 描述类型转换和显式向下转换的必要性 使用protected限制对数据和方法的访问 使用final修饰常量、不可覆盖的方法和不可继承的类 理解多态性、动态绑定 理解并掌握toString(),equals()方法的...

    protected修饰符与final修饰符.pptx

    会使用protected限制对数据和方法的访问会使用final修饰常量、不可覆盖的方法和不可继承的类11.14 protected 数据成员和方法子类和父类在同一包中,子类可以访问的部分: (1) 父类中public的成员; (2) 父类中...

    Java面试宝典(基础篇).docx

    与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。 重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型...

    类中的成员变量

    3种类的成员访问限制符//public 表示全局,公共,类内部外部子类都可以访问; //private表示私有的,只有本类内部可以使用; //protected表示受保护的,只有本类或子类或父类中可以访问;

    c#学习笔记——学习心得

    方法的重写:子类对父类方法的重新实现(方法头相同,方法体即代码块不同) 事件:是使得对像和类提供通知的成员。一个类通过提供事件声明来定义一个事件,这看起来与域和事件声明相当类似,但是有一个event关键字。...

    计算机(专升本)Java程序设计复习资料.doc

    重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回 类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常。 3. 抽象类与接口的异同 抽象类和接口都不能够实例化,但...

    java经典面试2010集锦100题(不看你后悔)

    B) 子类继承父类,那么子类可以重写父类的方法,但是一旦重写父类方法后,无法通过子类访问到父类的该方法。 C) 子类继承父类,如果父类中只有一个构造方法并且有参数,那么在子类的构造方法中必须先用super调用父类...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    通过父类和子类,我们实 现了类的的层次,可以从最一般的类开始,逐步特殊化,定义一系列的子类。同时,通过继 承也实现了代码的复用,使程序的复杂性线性地增长,而不是呈几何级数增长。 2.2.6 抽象 面向对象...

    C++中如何使类不能继承

    这样限制了子类的继承。所以我们可以将父类的构造函数声明成为私有的,但是这样父类不不能实例化。我想可以添加一个静态帮助函数来进行构造。虽然这样很简陋。但是这的确是一种解决方法。  可是如果只有这个方法...

    关于CSS 框架的论述

    最近看到N多介绍CSS框架,前些天我说过一句话:“在我有限的视野里,还没见到可以真正可以称...子类的实现很大程度上依赖于父类的实现,这种依赖性限制了重用的灵活性和完全性。但解决这种局限性的方法可以是只继承抽象

    解析C#的扩展方法

    当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写它或被其他更适合的类替换,这种依赖关系限制了灵活性并最终限制了复用性。替代继承特性的方式,较多的会采用 合成/聚合复用原则,“合成...

    C# 扩展方法小结

    当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写它或被其他更适合的类替换,这种依赖关系限制了灵活性并最终限制了复用性。替代继承特性的方式,较多的会采用 合成/聚合复用原则,“合成...

    net学习笔记及其他代码应用

    Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 接口(interface)是抽象类的变体。在接口中,所有方法...

    【05-面向对象(下)】

    •接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。 接口与抽象类的区别 •接口里只能包含抽象方法,不同包含已经提供实现的方法;抽象类则完全可以包含普通...

Global site tag (gtag.js) - Google Analytics