您的位置:首页 > 编程语言 > Java开发

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

2017-08-10 00:44 381 查看
多态,就是根据收到消息的不同而做不同的事情。

根据传入的对象的类型不同,在执行时去调用不同的方法是实现多态的一个重要手段。

多态存在的几个必要条件

①要有继承或者接口实现

②要有方法的覆盖或重写

③父类引用指向了子类的对象

方法的动态绑定

这是实现多态性的一个技术手段,在运行期间判断所引用对象的实际类型,根据实际类型去调用相应的方法。

[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…

注意区分依赖关系和关联关系的不同,什么时候该采取哪种关系,一个人养多个宠物和一个人只养一个宠物显然是用在不同场合的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: