一、多态简介:
多态是什么
多态性是同一事物或者同一事物的某个行为在不同的环境下有多种表现形态。
同一事物的多态性是指该对象类型的多态性,同一事物的某个行为的多态性是指对象的方法具有多态性。
所以多态性可以分为两大类:类型多态和方法多态,其中方法多态性又可以细分为重载多态和重写多态。
多态出现原因:
java的引用变量有两种类型:一个是编译时的类型,一个是运行时类型。
编译时类项:声明该变量时使用的类型决定。
运行时类项:实际赋给该变量的对象决定
如果编译时和运行时类项不一样就会出现所谓的多态。
注意:
1)引用变量在编译阶段只能调用其编译时类项所具有的方法,但运行时则执行运行时类项所具有的方法,因此编译java代码时,引用
变量只能调用声明该变量时类项里包含的方法,如:Object p = new Person()定义一个变量p,p只能调用Object类得方法而不能调用
person类里定义的方法。
2)属性不具有多态性
二、上转型对象:
1)上转型对象实体是子类创建的,
2)不能访问子类新增的成员,可以访问子类继承(等价于子类对象去调用这些方法)或者被子类屏蔽的成员
特别注意:只有普通的方法调用可以是多态的
静态的方法可以被继承,但是不能重写。如果父类中有一个静态的方法,子类也有一个与其方法名,参数类型,参数个数都一样的方法,
并且也有static关键字修饰,那么该子类的方法会把原来继承过来的父类的方法隐藏,而不是重写。通俗的讲就是父类的方法和子类的方法
是两个没有关系的方法,具体调用哪一个方法是看是哪个对象的引用;
三、重载多态:
同一类中具有不同方法签名的多个同名方法
1)方法名相同,参数不同(类型、顺序、个数)
2)与返回值和访问权限无关
需要补充的是,一个重载方法的参数如果有继承关系,那么具体调用哪个方法与参数类型有关。如果传递的实参与某个重载的形参满足“最大限度的匹配”,则调用那个重载方法。
下面例子说明最大限度匹配,注意test(Sheep)。
第1个test方法的实参“new Tiger()”是Tiger类型的对象,无法与Sheep匹配,只能与Animal匹配,所以执行的是test(Animal)方法;第2个test方法的实参“new Sheep()”可以与Animal匹配,也可以与Sheep匹配,根据最大匹配原理,调用test(Sheep)方法;显然第3个test方法的实参只能与Animal匹配。
public class Overload {
// 方法重载,参数是Animal型
public void test(Animal a) {
System.out.println("Animal");
}
// 方法重载,参数是Sheep型
public void test(Sheep s) {
System.out.println("Sheep");
}
public static void main(String[] args) {
Overload o = new Overload();
// 与test(Sheep)不匹配只能与test(Animal)匹配
o.test(new Tiger());
// 两个test方法都匹配,!!!!实际与test(Sheep)匹配
o.test(new Sheep());
// 与test(Animal)匹配
o.test(new Animal());
}
}
四、重写多态:
发生在父子类、中子类继承父类,子类定义了和父类相同方法签名的方法
1)方法名相同参数相同(方法签名相同)
2)访问权限不能比父类更严格
3)返回值可以是相同也可以是子类型
4)重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常。但是可以抛出更少,更有限或者不抛出异常。
注意:构造方法不能被继承 (构造方法要求名字必须与类名相同),因此不能重写Override,但可以被重载Overload。