三、多态
1、定义
- 多态是同一个行为具有多个不同表现形式或形态的能力。
- 多态就是同一个接口,使用不同的实例而执行不同操作。
- 多态就是对象多种表现形式的体现。
2、优点
- 可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
- 可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
- 接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
- 灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
- 简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
3、方法重载
定义
- 在Java中,同一个类中的多个方法可以有相同的方法名称,但是有不同的参数列表,这就称为方法重载。
- 参数列表又叫参数签名,包括参数的类型、参数的个数、参数的顺序,只要有一个不同就叫做参数列表不同。
重载分辨
- 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
栗子
public class Fjc {
//一个普通得方法,不带参数,无返回值
public void fjc(){
//method body
}
//重载上面的方法,并且带了一个整形参数,无返回值
public void fjc(int a){
//method body
}
//重载上面的方法,并且带了两个整型参数,返回值为int型
public int fjc(int a,int b){
//method body
return 0;
}
}
- 分析:
- 不难看出,方法重载就是在同一个类中,具有相同的方法名,但是参数列表不相同。
- 参数的个数不同、顺序不同、类型不同都可以被看作参数列表不同。但仅仅参数变量名称不同是不可以的。
- 跟成员方法一样,构造方法也可以重载。
规则
- 被重载的方法必须改变参数列表(参数个数或类型不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
4、方法重写
定义
- 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
- 子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
向上转型
-
定义
-
子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口。
-
格式
-
parent p = new son();
-
栗子
package fjchr;
class LWH {
public void jieshao() {
System.out.println("你好,我是LWH。");
}
}
class LTF extends LWH {
//子类根据自己的需求进行方法重写。
public void jieshao() {
System.out.println("你好,我是LTF。");
}
}
class ZJ extends LWH{
public void jieshao() {
//调用super访问父类成员。当需要在子类中调用父类的被重写方法时,要使用 super 关键字。
super.jieshao();
System.out.println("你好,我是ZJ。");
}
//子类单独定义的方法。
public void hobby() {
System.out.println("我喜欢吃饭。");
}
}
public class FJC{
public static void main(String[] args) {
//子类对象转为父类对象。
LTF zj =new LTF();
zj.jieshao();
LWH fjc = new LTF();
fjc.jieshao();
//子类对象转为父类对象。
LWH ltf =new ZJ();
ltf.jieshao();
//会报错,因为向上转型时,子类单独定义的方法会丢失。
//ltf.hobby();
}
}
- 分析:
- LWH fjc = new LTF();将子类对象 LTF转化为父类对象LWH。这个时候 LWH 这个引用调用的方法是子类方法。
- 子类单独定义的方法会丢失。比如上面ZJ类中定义的hobby方法,当LWH引用指向ZJ类实例时是访问不到hobby方法的,ltf.hobby()会报错。
- 子类引用不能指向父类对象。LTF c = (LTF)new LWH()这样是不行的。
- 当调用 zj.jieshao(); 时,编译器在编译时会在 LTF 类中找到 jieshao(),执行过程 JVM 就调用 LTF 类的 jieshao()。
- 因为 fjc 是 LWH 的引用,所以调用 fjc 的 jieshao() 方法时,编译器会去 LWH 类查找 jieshao() 方法 。
- 在编译的时候,编译器使用LWH 类中的 jieshao() 方法验证该语句, 但是在运行的时候,Java虚拟机(JVM)调用的是 LTF 类中的 jeishao() 方法。
- 运行结果为
你好,我是LTF。
你好,我是LTF。
你好,我是LWH。
你好,我是ZJ。
规则
- 参数列表必须完全与被重写方法的相同。
- 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7及更高版本可以不同)。
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
- 父类的成员方法只能被它的子类重写。
- 声明为 final 的方法不能被重写。
- 声明为 static 的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个方法,则不能重写这个方法。