重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说,子类能够根据需要实现父类的方法。重写需要遵守以下规则:
方法名必须相同
参数列表必须相同
修饰符的范围可以扩大,但不能缩小
抛出的异常可以被缩小,但不能扩大
示例:
Person类:
package com.wmwx.oop.Demo04; //父类:人类 public class Person { private int money = 10_0000_0000; protected String name = "惟妙惟霄"; public Person() { System.out.println("Person的无参构造方法执行了!"); } public void say(){ System.out.println("说了一句话。"); } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } public void print(){ System.out.println("Person"); } }Student类:
package com.wmwx.oop.Demo04; //子类:学生类 public class Student extends Person{ private String name = "妙霄"; public Student() { //隐藏代码:super(); //父类的构造方法必须要在子类的构造方法的第一行 System.out.println("Student的无参构造方法执行了!"); } public void test1(String name){ System.out.println(name); //输出参数 System.out.println(this.name); //输出当前类的name System.out.println(super.name); //输出父类的name } //重写都是方法的重写,与属性无关 //只允许重写public方法 //可以使用快捷键alt+insert来插入重写方法 @Override public void print() { System.out.println("Student"); } public void test2(){ print(); this.print(); super.print(); } }Application类:
package com.wmwx.oop; import com.wmwx.oop.Demo04.Person; import com.wmwx.oop.Demo04.Student; //启动类 public class Application { public static void main(String[] args) { Student student = new Student(); //第一行输出"Person的无参构造方法执行了!" //第二行输出"Student的无参构造方法执行了!" student.say(); //子类继承父类,就会拥有父类的public方法 System.out.println(student.getMoney()); //可以用父类的get/set方法对属性进行操作 //可以使用快捷键ctrl+H来查看继承树 student.test1("MiaoXiao"); //第一行输出"MiaoXiao" //第二行输出"妙霄" //第三行输出"惟妙惟霄" student.test2(); //第一行输出"Student" //第二行输出"Student" //第三行输出"Person" Student stu1 = new Student(); stu1.print(); //输出"Student" //父类的引用指向了子类 Person stu2 = new Student(); stu2.print(); //输出"Student" } } 多态多态是同一个行为具有多个不同表现形式或形态的能力。当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态存在的三个必要条件:
继承
重写
父类引用指向子类对象:Parent p = new Child();
不能被重写的方法:
static 方法
final 方法
private 方法
示例:
Person类:
package com.wmwx.oop.Demo05; public class Person { public void run(){ System.out.println("人在跑步。"); } }Student类:
package com.wmwx.oop.Demo05; public class Student extends Person{ @Override public void run() { System.out.println("学生在跑步。"); } public void eat(){ System.out.println("学生在吃东西。"); } }Application类:
package com.wmwx.oop; import com.wmwx.oop.Demo05.Person; import com.wmwx.oop.Demo05.Student; //启动类 public class Application { public static void main(String[] args) { //一个对象的实际类型是确定的 //但可以指向的引用类型是不确定的 Student s1 = new Student(); Person s2 = new Student(); //父类的引用指向子类 Object s3 = new Student(); s1.run(); //输出"学生在跑步" s2.run(); //子类重写父类方法,将执行子类方法,输出"学生在跑步。" s1.eat(); //输出"学生在吃东西" //s2.eat(); //不能调用。对象能使用哪些方法,要看左边的类型。 ((Student)s2).eat(); //强制类型转换。输出"学生在吃东西。" } } instanceof