起先向单刀直入的解决 Java 泛型的相关概念和应用,发现有一些概念不是很理解,于是发现是被卡在“协变和逆变”的概念上了,接着看,终于发现根源是在 Java 的多态。
Java 的多态
Java 的多态分为三种情况
特殊多态(Ad hoc polymorphism),此类下又包含函数重载(function overloading)以及类型转换多态(coercion polymorphism)
参数化多态(Parameteric polymorphism),对应到Java里即泛型。
子类型多态(Subtyping polymorphism),子类型多态,即通过类型继承关系获得的多态。
对于第三种情况有三个必要条件:
要有继承
要有重写
父类引用指向子类对象,这里涉及到向上转化,比如 Number n=new Integer(1);
依旧是针对第三种情况:
子类只能覆盖重写父类的非静态成员方法,常量(不管是否是静态的)、静态成员方法都是不可被覆盖的,而且,这种方式下,子类特有的方法不可以被直接访问。
Java 的向下转化和向上转化
我们以简单的代码来说明。
背景内容:子类 extends 父类,子类覆盖重写父类的普通成员方法,子类有一个自己特有的方法。
然后,父类 f=new 子类();
这个时候,f 是可以运行子类中的方法的,但是不能调用子类自己特有的方法,即虽然我们实例化的是子类,但是所能
调用的方法被局限在了父类的成员方法中,这个过程就是向上转化,Java 的多态是基于这一过程的。至于向下转化,如果通过声明父类而以子类实例化得到了对象a,把对象a强制类型转化为子类型,并赋值给一个新声明的子类型,这样也是可以的,而且子类型中自己特有的方法也可以调用了,类似于把父类对象转化为了子类型的对象,即向下转化。
再一个,向下转化并不体现多态,这只是一个强制转化的过程,而且,只有父类实例化对象是子类型时,才可能成功,换而言之,如果一个父类实例化对象是父类本身,其就不可以再被强制转化为子类对象了。
我们以简单的代码来说明,
背景内容:子类 extends 父类,子类覆盖重写父类的普通成员方法,子类有一个自己特有的方法。
然后,父类 f=new 子类();
这个时候,f 是可以运行子类中的方法的,但是不能调用子类自己特有的方法,即虽然我们实例化的是子类,但是所能
调用的方法被局限在了父类的成员方法中,这个过程就是向上转化,Java 的多态是基于这一过程的。至于向下转化,如果通过声明父类而以子类实例化得到了对象a,把对象a强制类型转化为子类型,并赋值给一个新声明的子类型,这样也是可以的,而且子类型中自己特有的方法也可以调用了,类似于把父类对象转化为了子类型的对象,即向下转化。
再一个,向下转化并不体现多态,这只是一个强制转化的过程,而且,只有父类实例化对象是子类型时,才可能成功,换而言之,如果一个父类实例化对象是父类本身,其就不可以再被强制转化为子类对象了。
class father{
public void m1(){
System.out.println("father.m1");
}
}
class son extends father{
@Override
public void m1(){
System.out.println("son.m1");
}
public void m2(){
System.out.println("son.m2");
}
}
public class JavaTest {
public static void main(String[] args) {
father f=new son();//向上转化
f.m1();//打印结果为 son.m1
son s=(son) f;//向下转化-强制转化的一种
s.m2();//打印结果为 son.m2
}
}