經典體現多態代碼語句:Fu fu = new Zi();
多態的體現:
父類的引用指向了自己的子類對象
父類的引用也可以接受自己的子類對象
多態的前提:
必須是類與類之間有關係,要麼繼承,要麼實現
存在覆蓋
多態的好處:
多態的出現大大的提高程序的擴展性
弊端:
提高了擴展性,但是隻能使用父類的引用訪問父類中的成員
多態中成員函數(非靜態)的特點:
編譯時期:參閱引用型變量所屬的類中是否有調用的方法,有則編譯成功,否則編譯失敗
運行時期:參閱對象所屬的類中是否有調用的方法
簡單總結:Fu fu = new Zi();成員函數在多態調用時,編譯看左邊,運行看右邊
示例代碼:
abstract class Animal{
abstract void eat();
}
class Cat extends Animal{
public void eat(){
System.out.println("喫魚");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("啃骨頭");
}
public void hanjiao(){
System.out.println("旺旺");
}
}
class Pig extends Animal{
public void eat(){
System.out.println("喫食");
}
public void gong(){
System.out.println("拱地");
}
}
public class Duotai{
public static void main(String[] args) {
Cat cat = new Cat();
function(cat);
Dog dog = new Dog();
function(dog);
Pig pig = new Pig();
function(pig);
/**父類的引用指向了自己的子類對象
* 父類的引用也可以接受自己的子類對象
* */
Animal ani = new Cat(); //類型提升(向上轉型)
ani.eat();
}
/**多態方式*/
public static void function(Animal ani){
ani.eat();
}
/**因爲Animal ani = new Cat(); 所以下邊的方法可以被上邊的function()替代*/
// public static void function(Cat cat){
// cat.eat();
// }
//
// public static void function(Dog dog){
// dog.eat();
// }
//
// public static void function(Pig pig){
// pig.eat();
// }
}
}
面試點:多態中,成員變量的特點
無論編譯和運行,都參考左邊 (引用型變量所屬的類)
靜態成員函數的特點:
無論編譯和運行,都參考左邊
package com.zy.jczyw.testcase;
class Fu{
int num = 5;
void method1() {
System.out.println("fu_method_1");
}
void method2() {
System.out.println("fu_method_2");
}
static void method4() {
System.out.println("fu_method_4");
}
}
class Zi extends Fu{
int num = 8;
void method1() {
System.out.println("zi_method_1");
}
void method3() {
System.out.println("zi_method_3");
}
static void method4() {
System.out.println("zi_method_4");
}
}
public class Duotai{
public static void main(String[] args) {
Zi z = new Zi();
z.method1(); //打印 zi_method_1
z.method2(); //打印 fu_method_2
z.method3(); //打印 zi_method_3
Fu f = new Zi();
f.method1(); //打印 zi_method_1 子類複寫了method1()
f.method2(); //打印 fu_method_2
//沒有f.method3() 因爲編譯時虛擬機未產生對象 new Zi(); 所以只有左邊Fu類的方法
System.out.println(f.num); //5
System.out.println(z.num); //8
f.method4(); //打印 fu_method_4
z.method4(); //打印 fu_method_5
}
}