【Java学习笔记】29:再谈多态性

来源:互联网 发布:caddy windows 编辑:程序博客网 时间:2024/05/18 02:00

多态,就是根据收到消息的不同而做不同的事情。
根据传入的对象的类型不同,在执行时去调用不同的方法是实现多态的一个重要手段。
多态存在的几个必要条件
①要有继承或者接口实现
②要有方法的覆盖或重写
③父类引用指向了子类的对象
方法的动态绑定
这是实现多态性的一个技术手段,在运行期间判断所引用对象的实际类型,根据实际类型去调用相应的方法。
[1]以接口示例

package day29;public class Test {    public static void main(String args[]){        //父类引用指向了子类的对象        Animal a1=new Dog();        Animal a2=new Cat();        Animal[] arrays={a1,a2};        for(Animal a:arrays){            a.eat();            a.sleep();        }    }}interface Animal{    public void eat();    public void sleep();}//要有继承或者接口实现class Dog implements Animal{    public void eat(){        System.out.println("Dog eating...");    }    public void sleep(){        System.out.println("Dog sleeping...");    }}class Cat implements Animal{    //要有方法的覆盖或重写    public void eat(){        System.out.println("Cat eating...");    }    public void sleep(){        System.out.println("Cat sleeping...");    }}

运行结果:
Dog eating…
Dog sleeping…
Cat eating…
Cat sleeping…

[2]以继承示例

package day29;public class Test {    public static void main(String args[]){        //父类引用指向了子类的对象        Person p1=new Students();        Person p2=new Teachers();        Person[] persons={p1,p2};        for(Person p:persons){            p.eat();            p.sleep();        }    }}abstract class Person{    abstract public void eat();    abstract public void sleep();}//要有继承或者接口实现class Students extends Person{    public void eat(){        System.out.println("Students eating...");    }    public void sleep(){        System.out.println("Students sleeping...");    }}class Teachers extends Person{    //要有方法的覆盖或重写    public void eat(){        System.out.println("Teachers eating...");    }    public void sleep(){        System.out.println("Teachers sleeping...");    }}

运行结果:
Students eating…
Students sleeping…
Teachers eating…
Teachers sleeping…

[3]方法传参的例子

package day29;public class Test {    public static void main(String args[]){        //父类引用指向了子类的对象        Animal a1=new Dog();        Animal a2=new Cat();        Owner o=new Owner();        o.care(a1);        o.care(a2);    }}interface Animal{    public void eat();    public void sleep();}//要有继承或者接口实现class Dog implements Animal{    public void eat(){        System.out.println("Dog eating...");    }    public void sleep(){        System.out.println("Dog sleeping...");    }}class Cat implements Animal{    //要有方法的覆盖或重写    public void eat(){        System.out.println("Cat eating...");    }    public void sleep(){        System.out.println("Cat sleeping...");    }}class Owner{    //方法传递的是父类的参数    public void care(Animal a)    {        a.eat();        a.sleep();    }}

运行结果:
Dog eating…
Dog sleeping…
Cat eating…
Cat sleeping…

引用类型的类型转换
可以分为向上类型转换(自动)和向下类型转换(强制),和基本数据类型的类型转换相仿——强制的类型转换都可能会造成异常。
引用的类型转换,类型间是有关系的,要么是继承的关系,要么是接口实现的关系。
[1]指鹿为马的例子(报错)

package day29;public class Test {    public static void main(String args[]){        Deer d=new Deer();        Horse h=(Horse)d;    }}class Deer{}class Horse{}

运行结果:
Exception in thread “main” java.lang.Error: 无法解析的编译问题:
不能从 Deer 强制类型转换为 Horse

[2]有继承关系的转换

package day29;public class Test {    public static void main(String args[]){        //子类向父类:自动向上转换        Deer d1=new Deer();        Animal a1=d1;        //父类向子类:强制向下转换,编译期没问题,可能出现运行期异常(试将第10行Deer改成Animal)        Animal a2=new Deer();        Deer d2=(Deer)a2;    }}class Animal{}class Deer extends Animal{}

[3]有接口关系的转换

package day29;public class Test {    public static void main(String args[]){        Pet pet=new Cat();        Cat c=(Cat)pet;//接口建立的实例向实现接口的类:强制向下转换,编译期没问题,可能出现运行期异常    }}interface Pet{}class Cat implements Pet{}

多态

package day29;public class Test {    public static void main(String args[]){        MP3 mp3=new Mobile();        mp3.PlayMusic();        mp3=new Computer();        mp3.PlayMusic();    }}interface MP3{    public void PlayMusic();}class Mobile implements MP3{    public void PlayMusic(){        System.out.println("播放手机MP3.");    }}class Computer implements MP3{    public void PlayMusic(){        System.out.println("播放电脑MP3.");    }}

运行结果:
播放手机MP3.
播放电脑MP3.

package day29;public class Test {    public static void main(String args[]){        Person p1=new Person();        p1.use(new Mobile());        p1.use(new Computer());    }}class Person{    //依赖抽象非具体从而实现多态    public void use(MP3 mp3){        mp3.PlayMusic();    }}interface MP3{    public void PlayMusic();}class Mobile implements MP3{    public void PlayMusic(){        System.out.println("播放手机MP3.");    }}class Computer implements MP3{    public void PlayMusic(){        System.out.println("播放电脑MP3.");    }}

运行结果:
播放手机MP3.
播放电脑MP3.

package day29;public class Test {    public static void main(String args[]){        Person p1=new Person(new Mobile());        p1.use();        Person p2=new Person(new Computer());        p2.use();    }}class Person{    public MP3 mp3;    //关联关系,关联抽象(的MP3接口)而非具体(的Mobile类或Computer类)    public Person(MP3 mp3){        this.mp3=mp3;    }    public void use(){        mp3.PlayMusic();    }}interface MP3{    public void PlayMusic();}class Mobile implements MP3{    public void PlayMusic(){        System.out.println("播放手机MP3.");    }}class Computer implements MP3{    public void PlayMusic(){        System.out.println("播放电脑MP3.");    }}

运行结果:
播放手机MP3.
播放电脑MP3.

package day29;public class Test {    public static void main(String args[]){        Person p1=new Person(new Dog());        p1.care();        Person p2=new Person(new Cat());        p2.care();    }}class Person{    public Animal a;    //关联关系,关联抽象(的Animal父类)而非具体(的Dog类或Cat类)    public Person(Animal a){        this.a=a;    }    public void care(){        a.play();    }}abstract class Animal{    abstract public void play();}class Dog extends Animal{    public void play(){        System.out.println("Dog play...");    }}class Cat extends Animal{    public void play(){        System.out.println("Cat play...");    }}

运行结果:
Dog play…
Cat play…

package day29;public class Test {    public static void main(String args[]){        Person p=new Person();        p.care(new Dog());        p.care(new Cat());    }}class Person{    public Person(){    }    //依赖关系,依赖抽象(的Animal父类)而非具体(的Dog类或Cat类)    public void care(Animal a){        a.play();    }}abstract class Animal{    abstract public void play();}class Dog extends Animal{    public void play(){        System.out.println("Dog play...");    }}class Cat extends Animal{    public void play(){        System.out.println("Cat play...");    }}

运行结果:
Dog play…
Cat play…

注意区分依赖关系和关联关系的不同,什么时候该采取哪种关系,一个人养多个宠物和一个人只养一个宠物显然是用在不同场合的。

原创粉丝点击