【Java学习笔记】29:再谈多态性
2017-08-10 00:44
381 查看
多态,就是根据收到消息的不同而做不同的事情。
根据传入的对象的类型不同,在执行时去调用不同的方法是实现多态的一个重要手段。
多态存在的几个必要条件
①要有继承或者接口实现
②要有方法的覆盖或重写
③父类引用指向了子类的对象
方法的动态绑定
这是实现多态性的一个技术手段,在运行期间判断所引用对象的实际类型,根据实际类型去调用相应的方法。
[1]以接口示例
运行结果:
Dog eating…
Dog sleeping…
Cat eating…
Cat sleeping…
[2]以继承示例
运行结果:
Students eating…
Students sleeping…
Teachers eating…
Teachers sleeping…
[3]方法传参的例子
运行结果:
Dog eating…
Dog sleeping…
Cat eating…
Cat sleeping…
引用类型的类型转换
可以分为向上类型转换(自动)和向下类型转换(强制),和基本数据类型的类型转换相仿——强制的类型转换都可能会造成异常。
引用的类型转换,类型间是有关系的,要么是继承的关系,要么是接口实现的关系。
[1]指鹿为马的例子(报错)
运行结果:
Exception in thread “main” java.lang.Error: 无法解析的编译问题:
不能从 Deer 强制类型转换为 Horse
[2]有继承关系的转换
[3]有接口关系的转换
多态
运行结果:
播放手机MP3.
播放电脑MP3.
运行结果:
播放手机MP3.
播放电脑MP3.
运行结果:
播放手机MP3.
播放电脑MP3.
运行结果:
Dog play…
Cat play…
运行结果:
Dog play…
Cat play…
注意区分依赖关系和关联关系的不同,什么时候该采取哪种关系,一个人养多个宠物和一个人只养一个宠物显然是用在不同场合的。
根据传入的对象的类型不同,在执行时去调用不同的方法是实现多态的一个重要手段。
多态存在的几个必要条件
①要有继承或者接口实现
②要有方法的覆盖或重写
③父类引用指向了子类的对象
方法的动态绑定
这是实现多态性的一个技术手段,在运行期间判断所引用对象的实际类型,根据实际类型去调用相应的方法。
[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(){ f2a7 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…
注意区分依赖关系和关联关系的不同,什么时候该采取哪种关系,一个人养多个宠物和一个人只养一个宠物显然是用在不同场合的。
相关文章推荐
- JAVA学习笔记二:类的继承、多态性
- 3.28-29学习笔记——JAVA控制流程和数组
- java学习笔记—第三方数据库连接池包1(29)
- Java学习笔记---16.面向对象编程11-Java多态性,instanceof及Object类
- 学习笔记之JavaSE(29)--JavaAPI详解4
- Java之学习笔记(29)-----------static
- 【Java学习笔记之二十四】对Java多态性的一点理解
- [学习笔记]Java多态性
- Java学习笔记——多态性Polymorphism
- Java学习笔记-多态性
- ElasticSearch 6.x 学习笔记:29.Java API之Match All Query
- 【Java学习笔记之二十四】对Java多态性的一点理解
- 【学习笔记】Thinking in java (第三版)第七章 多态性(Polymorphism)
- Java学习笔记:类在继承中的多态性
- 黑马程序员_JAVA 学习笔记29 WEB篇16
- Java学习笔记29 内部类(Inner Cla…
- java学习笔记29
- Java 学习笔记(0x0B) 动态绑定与多态性
- Java学习笔记29(集合框架三:泛型)
- (29)Java学习笔记——常用对象 / System 类