我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java 重写时应当遵守的 11 条规则

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java 重写时应当遵守的 11 条规则

CSDN 的小伙伴们,大家好,我是沉默王二。

重写(Overriding)算是 Java 中一个非常重要的概念,理解重写到底是什么对每个 Java 程序员来说都至关重要,这篇文章就来给大家说说重写过程中应当遵守的 12 条规则。

01、什么是重写?

重写带来了一种非常重要的能力,可以让子类重新实现从超类那继承过来的方法。在下面这幅图中,Animal 是父类,Dog 是子类,Dog 重新实现了 move() 方法用来和父类进行区分,毕竟狗狗跑起来还是比较有特色的。

重写的方法和被重写的方法,不仅方法名相同,参数也相同,只不过,方法体有所不同。

02、哪些方法可以被重写?

规则一:只能重写继承过来的方法。

因为重写是在子类重新实现从父类继承过来的方法时发生的,所以只能重写继承过来的方法,这很好理解。这就意味着,只能重写那些被 public、protected 或者 default 修饰的方法,private 修饰的方法无法被重写。

Animal 类有 move()eat()sleep() 三个方法:


public class Animal {
 public void move() { }

 protected void eat() { }
 
 void sleep(){ }
}

Dog 类来重写这三个方法:


public class Dog extends Animal {
 public void move() { }

 protected void eat() { }

 void sleep(){ }
}

OK,完全没有问题。但如果父类中的方法是 private 的,就行不通了。


public class Animal {
 private void move() { }
}

此时,Dog 类中的 move() 方法就不再是一个重写方法了,因为父类的 move() 方法是 private 的,对子类并不可见。


public class Dog extends Animal {
 public void move() { }
}

03、哪些方法不能被重写?

规则二:final、static 的方法不能被重写。

一个方法是 final 的就意味着它无法被子类继承到,所以就没办法重写。


public class Animal {
 final void move() { }
}

由于父类 Animal 中的 move() 是 final 的,所以子类在尝试重写该方法的时候就出现编译错误了!

同样的,如果一个方法是 static 的,也不允许重写,因为静态方法可用于父类以及子类的所有实例。


public class Animal {
 final void move() { }
}

重写的目的在于根据对象的类型不同而表现出多态,而静态方法不需要创建对象就可以使用。没有了对象,重写所需要的“对象的类型”也就没有存在的意义了。

04、重写方法的要求

规则三:重写的方法必须有相同的参数列表。


public class Animal {
 void eat(String food) { }
}

Dog 类中的 eat() 方法保持了父类方法 eat() 的同一个调调,都有一个参数——String 类型的 food。


public class Dog extends Animal {
 public void eat(String food) { }
}

一旦子类没有按照这个规则来,比如说增加了一个参数:


public class Dog extends Animal {
 public void eat(String food, int amount) { }
}

这就不再是重写的范畴了,当然也不是重载的范畴,因为重载考虑的是同一个类。

规则四:重写的方法必须返回相同的类型。

父类没有返回类型:


public class Animal {
 void eat(String food) { }
}

子类尝试返回 String:


public class Dog extends Animal {
 public String eat(String food) {
  return null;
 }
}

于是就编译出错了(返回类型不兼容)。

规则五:重写的方法不能使用限制等级更严格的权限修饰符。

可以这样来理解:

  • 如果被重写的方法是 default,那么重写的方法可以是 default、protected 或者 public。
  • 如果被重写的方法是 protected,那么重写的方法只能是 protected 或者 public。
  • 如果被重写的方法是 public, 那么重写的方法就只能是 public。

举个例子,父类中的方法是 protected:


public class Animal {
 protected void eat() { }
}

子类中的方法可以是 public:


public class Dog extends Animal {
 public void eat() { }
}

如果子类中的方法用了更严格的权限修饰符,编译器就报错了。

规则六:重写后的方法不能抛出比父类中更高级别的异常。

举例来说,如果父类中的方法抛出的是 IOException,那么子类中重写的方法不能抛出 Exception,可以是 IOException 的子类或者不抛出任何异常。这条规则只适用于可检查的异常。

可检查(checked)异常必须在源代码中显式地进行捕获处理,不检查(unchecked)异常就是所谓的运行时异常,比如说 NullPointerException、ArrayIndexOutOfBoundsException 之类的,不会在编译器强制要求。

父类抛出 IOException:


public class Animal {
 protected void eat() throws IOException { }
}

子类抛出 FileNotFoundException 是可以满足重写的规则的,因为 FileNotFoundException 是 IOException 的子类。


public class Dog extends Animal {
 public void eat() throws FileNotFoundException { }
}

如果子类抛出了一个新的异常,并且是一个 checked 异常:


public class Dog extends Animal {
 public void eat() throws FileNotFoundException, InterruptedException { }
}

那编译器就会提示错误:

Error:(9, 16) java: com.itwanger.overriding.Dog中的eat()无法覆盖com.itwanger.overriding.Animal中的eat()
被覆盖的方法未抛出java.lang.InterruptedException

但如果子类抛出的是一个 unchecked 异常,那就没有冲突:


public class Dog extends Animal {
 public void eat() throws FileNotFoundException, IllegalArgumentException { }
}

如果子类抛出的是一个更高级别的异常:


public class Dog extends Animal {
 public void eat() throws Exception { }
}

编译器同样会提示错误,因为 Exception 是 IOException 的父类。

Error:(9, 16) java: com.itwanger.overriding.Dog中的eat()无法覆盖com.itwanger.overriding.Animal中的eat()
被覆盖的方法未抛出java.lang.Exception

05、如何调用被重写的方法?

规则七:可以在子类中通过 super 关键字来调用父类中被重写的方法。

子类继承父类的方法而不是重新实现是很常见的一种做法,在这种情况下,可以按照下面的形式调用父类的方法:


super.overriddenMethodName();

来看例子。


public class Animal {
 protected void eat() { }
}

子类重写了 eat() 方法,然后在子类的 eat() 方法中,可以在方法体的第一行通过 super.eat() 调用父类的方法,然后再增加属于自己的代码。


public class Dog extends Animal {
 public void eat() {
  super.eat();
  // Dog-eat
 }
}

06、重写和构造方法

规则八:构造方法不能被重写。

因为构造方法很特殊,而且子类的构造方法不能和父类的构造方法同名(类名不同),所以构造方法和重写之间没有任何关系。

07、重写和抽象方法

规则九:如果一个类继承了抽象类,抽象类中的抽象方法必须在子类中被重写。

先来看这样一个接口类:


public interface Animal {
 void move();
}

接口中的方法默认都是抽象方法,通过反编译是可以看得到的:


public interface Animal
{
 public abstract void move();
}

如果一个抽象类实现了 Animal 接口,move() 方法不是必须被重写的:


public abstract class AbstractDog implements Animal {
 protected abstract void bark();
}

但如果一个类继承了抽象类 AbstractDog,那么 Animal 接口中的 move() 方法和抽象类 AbstractDog 中的抽象方法 bark() 都必须被重写:


public class BullDog extends AbstractDog {
 
 public void move() {}
 
 protected void bark() {}
}

08、重写和 synchronized 方法

规则十:synchronized 关键字对重写规则没有任何影响。

synchronized 关键字用于在多线程环境中获取和释放监听对象,因此它对重写规则没有任何影响,这就意味着 synchronized 方法可以去重写一个非同步方法。

09、重写和 strictfp 方法

规则十一:strictfp 关键字对重写规则没有任何影响。

如果你想让浮点运算更加精确,而且不会因为硬件平台的不同导致执行的结果不一致的话,可以在方法上添加 strictfp 关键字。因此 strictfp 关键和重写规则无关。

到此这篇关于Java 重写时应当遵守的 11 条规则的文章就介绍到这了,更多相关Java 重写规则内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java 重写时应当遵守的 11 条规则

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

在Java中使用重写时需要遵循哪些规则

在Java中使用重写时需要遵循哪些规则?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。01、什么是重写?重写带来了一种非常重要的能力,可以让子类重新实现从超类那继
2023-06-14

java进程同步的几个重要概念以及同步机制应该遵循的规则

这篇文章主要介绍“java进程同步的几个重要概念以及同步机制应该遵循的规则”,在日常操作中,相信很多人在java进程同步的几个重要概念以及同步机制应该遵循的规则问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”j
2023-06-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录