编译时类项:声明该变量时使用的类型决定。
运行时类项:实际赋给该变量的对象决定
如果编译时和运行时类项不一样就会出现所谓的多态(polymorphism)。
多态:相同类项的变量执行同一个方法时,呈现出不同的行为特征这就是多态。
注意:引用变量在编译阶段只能调用其编译时类项所具有的方法,但运行时则执行运行时类项所具有的方法,因此编译java代码时,引用变量只能调用声明该变量时类项里包含的方法,如:Object p = new Person()定义一个变量p,p只能调用Object类得方法而不能调用person类里定义的方法。
与方法不同的是对象的属性则不具有多态性:
。子类对象可以直接赋给父类引用,但父类对象在任何情况下都不可以直接赋给子类引用,因为子类是父类的一种
。父类引用强制类型转换为子类的前提是 该父类引用定义时指向子类对象,而不是指向父类对象 :animal an = new cat(); 可以
要想发生向下转型 则必须先有向上转型,表示建立关联, 只有 对象引用 instanceof classname 为 true的时候才能发生
向下转型
。通过父类引用只能访问子类对象从父类继承过来的成员
。通过父类引用不能访问子类对象所特有的成员
。多态前提: 要有继承, 要有重写, 父类引用指向子类对象
。成员方法(非static)在多态调用时,编译看左边,运行看右边: aa1.f();
编译时,参阅引用所属的类(父类)是否有调用的方法,有则编译成功,没有则编译失败
运行时,参阅对象( 引用.new()中的new ) 所属的 类 中的方法,运行该类中的方法(而不是引用所属的类中的方法)
static 方法调用时与下边所说的变量一致,与 非static 不一样(非static方法有重写特性)
public class Wine {
public void fun1(){
System.out.println("Wine 的Fun.....");
fun2();
}
public void fun2(){
System.out.println("Wine 的Fun2...");
}
}
public class JNC extends Wine{
/**
* @desc 子类重载父类方法
* 父类中不存在该方法,向上转型后,父类是不能引用该方法的
* @param a
* @return void
*/
public void fun1(String a){
System.out.println("JNC 的 Fun1...");
fun2();
}
/**
* 子类重写父类方法
* 指向子类的父类引用调用fun2时,必定是调用该方法
*/
public void fun2(){
System.out.println("JNC 的Fun2...");
}
}
public class Test {
public static void main(String[] args) {
Wine a = new JNC();
a.fun1();
}
}
-------------------------------------------------
Output:
Wine 的Fun.....
JNC 的Fun2...
1、类多态性表现
(1)方法重载
重载表现为同一个类中方法的多态性.一个类生命多个重载方法就是为一种功能提供多种实现.编译时,根据方法实际参数的数据类型/个数和次序,决定究竟应该执行重载方法中的哪一个.
(2)子类重定义从父类继承来的成员
当子类从父类继承来的成员不适合子类时,子类不能删除它们,但可以重定义它们,使弗雷成员适应子类的新需求.子类重定义父类成员,同名成员在父类与子类之间表现出多态性,父类对象引用父类成员,子类对象引用子类成员,不会产生冲突和混乱.
子类可重定义父类的同名成员变量,称子类隐藏父类成员变量.子类也可以重定义父类的同名成员方法,当子类方法的参数列表与父类方法参数列表完全相同时,称为子类方法覆盖(override)父类方法。覆盖父类方法时,子类方法的访问权限不能小于父类方法的权限。
由于Object类的equals()方法比较两个对象的引用是否相等而不是值是否相等,因此一个类要覆盖Object类的equals()方法,提供本类两个对象比较相等方法.
覆盖表现为父类与子类之间方法的多态性.java 寻找执行方法的原则是:从对象所属的类开始,寻找匹配的方法执行,如果当前类中没有匹配的方法,则逐层向上依次在父类或祖先类中寻找匹配方法,直到Object类.