多态

概述:Polymorphismm同一个方法调用,由于对象不同会有不同的行为。

多态条件:重写、继承、引用(父类引用子类对象)。

父类引用指向子类对象并该父类引用调用子类重写的方法,此时就出现多态。

引用变量的两种类型

  • 编译时类型:由声明类型决定,一般是父类。

  • 运行时类型:由实际对应的类型决定,一般是子类。

比如:

AnimalPoly ap1 = new BirdPoly();

AnimalPoly是编译时类型,BirdPoly是运行时类型。

多态的好处:我们不用针对每一个具体对象都去写相应的方法,直接通过父类对象辨别具体对象去引用,找到重载的方法输出即可。

示例:

package com.itcode.demo;  

/**      
 * @author: 成都码到功成学员  
 * @description:  
 * 多态 
 * 多态条件:重写、继承、引用(父类引用子类对象) 
 */  
class AnimalPoly{  

    public void shout() {  
        System.out.println("动物叫");  
    }  
}  

// 多态条件:继承  
class CatPoly extends AnimalPoly{  

    // 多态条件:重写  
    public void shout() {  
        System.out.println("喵喵");  
    }  
}  

class DogPoly extends AnimalPoly{  

    // 多态条件:重写  
    public void shout() {  
        System.out.println("汪汪");  
    }  
}  

class BirdPoly extends AnimalPoly{  

    // 多态条件:重写  
    public void shout() {  
        System.out.println("啾啾");  
    }  
}  


public class TestPoly {  

    public static void main(String[] args) {  
        DogPoly dp = new DogPoly();  
        // 多态条件:引用(父类引用子类对象)  
        animalShout(dp); // 汪汪  
        CatPoly cp = new CatPoly();  
        animalShout(cp);// 喵喵   
        BirdPoly bp = new BirdPoly();  
        animalShout(bp);// 啾啾  
        AnimalPoly ap = new AnimalPoly();  
        animalShout(ap);// 动物叫  

        // 当然也可以这样调用,效果也类似。  
        AnimalPoly ap1 = new BirdPoly();  
        animalShout(ap1);// 啾啾  
    }  

    // 父类引用指向子类对象并该父类引用调用子类重写的方法,此时就出现多态。  
    static void animalShout(AnimalPoly a) {  
        a.shout();  
    }  
}

示例2:关于多态运行分析

package com.itcode.demo;  

/**      
 * @author: 成都码到功成学员  
 * @description:  
 * 多态内存分析 
 * 多态条件:重写、继承、引用(父类引用子类对象) 
 */  
class AnimalPoly2{  

    public void shout() {  
        System.out.println("动物叫");  
    }  
}  

// 多态条件:继承  
class CatPoly2 extends AnimalPoly2{  

    // 多态条件:重写  
    public void shout() {  
        System.out.println("喵喵");  
    }  
}  

class DogPoly2 extends AnimalPoly2{  

    // 多态条件:重写  
    public void shout() {  
        System.out.println("汪汪");  
    }  
}  

class BirdPoly2 extends AnimalPoly2{  

    // 多态条件:重写  
    public void shout() {  
        System.out.println("啾啾");  
    }  
}  


public class TestPoly2 {  

    public static void main(String[] args) {  

        // 当使用AnimalPoly2类型时,在animalPoly方法里判断类型是AnimalPoly2,直接让ap1进入其方法。  
        AnimalPoly2 ap1 = new BirdPoly2();  
        animalShout(ap1);// 啾啾  

        /* 当使用BirdPoly2类型时,在animalPoly方法里判断类型虽然不是AnimalPoly2, 
         * 但是BirdPoly2是AnimalPoly2的子类,小于AnimalPoly2类型,所以可以直接让bp进入其方法。 */  
        BirdPoly2 bp = new BirdPoly2();  
        animalShout(bp);// 啾啾  

        /*  
         * 有点类似这个 
         * aaa方法里两个参数类型都是long,但是我们传入的实参都是byte类型。 
         * byte类型小于long类型,所以可以直接使用,输出结果是25 
         *  */  
        byte aa = 12;  
        byte bb = 13;  
        aaa(aa, bb);// 25  
    }  

    // 父类引用指向子类对象并该父类引用调用子类重写的方法,此时就出现多态。  
    static void animalShout(AnimalPoly2 a) {  
        a.shout();  
    }  

    static void aaa(long a, long b) {  
        System.out.println(a+b);  
    }  
}

对象转型

向上转型:编译类型>声明类型,小转大,自动转。 编译看左,运行看右。

如:Animal a = new Cat();

向下转型:编译类型<声明类型,大转小,强转。可以使用子类特有方法。编译看左,运行看右。

比如:Cat c = (Cat)new Animal;

或者

Animal a = new Cat();
Cat c = (Cat)a;

示例

package com.itcode.demo;  

/**      
 * @author: 成都码到功成学员  
 * @description:  
 * 多态 
 * 多态条件:重写、继承、引用(父类引用子类对象) 
 */  
class AnimalPoly3{  

    public void shout() {  
        System.out.println("动物叫");  
    }  

    private void study() {  
        System.out.println("动物学习");  
    }  
}  

// 多态条件:继承  
class CatPoly3 extends AnimalPoly3{  

    // 多态条件:重写  
    public void shout() {  
        System.out.println("喵喵");  
    }  

    public void catchMouse() {  
        System.out.println("抓老鼠");  
    }  
}  

class DogPoly3 extends AnimalPoly3{  

    // 多态条件:重写  
    public void shout() {  
        System.out.println("汪汪");  
    }  
}  

class BirdPoly3 extends AnimalPoly3{  

    // 多态条件:重写  
    public void shout() {  
        System.out.println("啾啾");  
    }  

    public void fly() {  
        System.out.println("看,飞鸟");  
    }  
}  


public class TestPoly3 {  

    public static void main(String[] args) {  
        // 向上转型  
        AnimalPoly3 an = new CatPoly3();  

        // 向下转型 调用子类特有方法catchMouse  
        AnimalPoly3 ac3 = new AnimalPoly3();  
        CatPoly3 c3 = (CatPoly3) an;  
        c3.catchMouse();  

        /* 
         *  向下转型易遇到的问题 
         *  这儿编译能通过,但是运行会报错。ClassCastException 类转换异常 
         *  因为声明类型BirdPoly3和编译类型DogPoly3是同一等级但是不同类型的对象。 
         *  简单来说,向上/下转型中引用类型的编译类型只能是声明类型的子类/父类或者就是其本身。 
         */       
        AnimalPoly3 ad3 = new DogPoly3();  
//      BirdPoly3 ba3 = (BirdPoly3) ad3;  
    }  

    // 父类引用指向子类对象并该父类引用调用子类重写的方法,此时就出现多态。  
    static void animalShout(AnimalPoly a) {  
        a.shout();  
    }  
}

final

修饰变量:值不能被修改。

修饰方法:不能被重写,但可以重载。

修饰类:不能被继承。

package com.itcode.demo3;  

/** 
 * @Auther: 成都码到功成学员 
 * @Description: 
 * final 
 */  
final class FinalFf{  
}  
class FinalF{  
    final int MAX = 5;  
    final void show(){  
        System.out.println("show");  
    }  
    // 可以被重载  
    void show(String name){  
        System.out.println("show"+name);  
    }  
}  
class FinalS extends FinalF/*extends FinalFf 报错*/{  
    // 不能被重写  
//    public void show(){  
//        System.out.println("");  
//    }  
}

Last updated

Was this helpful?