Fork me on GitHub

Java从零开始学十六(多态)

一、什么是多态

多态性是指允许不同类的对象对同一消息作出响应.多态性包括参数化多态性和包含多态性.多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题.
多态有两种表现形式:重载和覆盖
首先说重载(overload),是发生在同一类中.与什么父类子类、继承毫无关系.
标识一个函数除了函数名外,还有函数的参数(个数和类型).也就是说,一个类中可以有两个或更多的函数,叫同一个名字而他们的参数不同.
他们之间毫无关系,是不同的函数,只是可能他们的功能类似,所以才命名一样,增加可读性,仅此而已!
再说覆盖(override),是发生在子类中!也就是说必须有继承的情况下才有覆盖发生.
我们知道继承一个类,也就有了父类了全部方法,如果你感到哪个方法不爽,功能要变,那就把那个函数在子类中重新实现一遍.
这样再调用这个方法的时候,就是执行子类中的过程了.父类中的函数就被覆盖了.(当然,覆盖的时候函数名和参数要和父类中完全一样,不然你的方法对父类中的方法就不起任何作用,因为两者是两个函数,毫不关系)

二、简单实现

package com.pb.demo6;

public abstract class Pet {
   private String name;  //宠物名字
   private String sex;    //宠物性别
   private int health;        //宠物的健康值
   
   //宠物看病的方法
   abstract void toHospital();

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getSex() {
    return sex;
}

public void setSex(String sex) {
    this.sex = sex;
}

public int getHealth() {
    return health;
}

public void setHealth(int health) {
    this.health = health;
}
   
}
package com.pb.demo6;
/*
 * 小狗类
 */
public class Dog extends Pet {

    @Override
    void toHospital() {
        //小狗看病的方法
        System.out.println("小狗看病:打针、吃药!");

    }

}

package com.pb.demo6;
/*
 * 小猪类
 */
public class Pig extends Pet {

    @Override
    void toHospital() {
        System.out.println("小猪看病:打针、睡觉!");

    }

}
package com.pb.demo6;
/*
 * 小鸟类
 */
public class Bird extends Pet {

    @Override
    void toHospital() {
        //小鸟看病的方法
        System.out.println("小鸟看病:吃药、休息!");

    }

}
package com.pb.demo6;
/*
 * 宠物医生类
 */
public class Doctor {
    
    //医生治疗方法
    public void cure(Pet pet){ //将宠物传参
        
        if(pet.getHealth()<50){ //判断健康值小于50
            //调用看病的方法
            pet.toHospital();
            //将健康值设置为60,健康
            pet.setHealth(60);
        }
    }

}

测试类

package com.pb.demo6;
/*
 * 测试类
 */
public class Test {

    public static void main(String[] args) {
        //声明医生对象
        Doctor dc=new Doctor();
        //声明宠物对象为小鸟
       Pet brid=new Bird();
       //调用医生的治疗方法
       dc.cure(brid);
     //声明宠物对象为小狗
       Pet dog=new Dog();
     //调用医生的治疗方法
       dc.cure(dog);
     //声明宠物对象为小猪
       Pet pig=new Pig();
     //调用医生的治疗方法
       dc.cure(pig);
       
    }

}

结果:

小鸟看病:吃药、休息!
小狗看病:打针、吃药!
小猪看病:打针、睡觉!

三、对象的多态性

 对象的多态性主要分为以下两种类型:
向上转型和向下转型

3.1 对象向上转型:

父类 父类对象 = 子类实例 ;
向上转型:子类对象 ->父类对象
对于向上转型,程序会自动完成,格式:
如上面的:
 //声明宠物对象为小鸟
       Pet brid=new Bird();
//声明宠物对象为小狗
       Pet dog=new Dog();
 //声明宠物对象为小猪
       Pet pig=new Pig();

编译时类型为:Pet,而运行时类型为具体的类型

也就是说编译时类型由声明该变量时使用类型决定,而运行时类型由实际赋给该变量的对象决定

3.2 对象向下转型:

向下转型:父类对象 ->子类对象
对于向下转型时,必须明确的指明要转型的子类类型,格式:
子类 子类对象 = (子类)父类实例 ;强制类型转换
 
 上面的例中,子类没有自己的方法,如果子类有自己的方法,医生类中还能调用吗?显然不能,因为是向上转为父类后,只能调用父类的方法,如果要调用子类的方法就需要用到向下转型要用到instannceof

四、instanceof 关键字

在java中可以使用instanceof关键字判断一个对象到底是那个类的实例
对象 instanceof 类   ->返回boolean类型
package com.pb.demo6;

public abstract class Pet {
   private String name;  //宠物名字
   private String sex;    //宠物性别
   private int health;        //宠物的健康值
   
   //宠物看病的方法
   abstract void toHospital();

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getSex() {
    return sex;
}

public void setSex(String sex) {
    this.sex = sex;
}

public int getHealth() {
    return health;
}

public void setHealth(int health) {
    this.health = health;
}
   
}
package com.pb.demo6;
/*
 * 小鸟类
 */
public class Bird extends Pet {

    @Override
    void toHospital() {
        //小鸟看病的方法
        System.out.println("小鸟看病:吃药、休息!");

    }
    public void fly(){
        System.out.println("小鸟会飞!");
    }

}
package com.pb.demo6;
/*
 * 小狗类
 */
public class Dog extends Pet {

    @Override
    void toHospital() {
        //小狗看病的方法
        System.out.println("小狗看病:打针、吃药!");

    }
    public void run(){
        System.out.println("小狗在地上跑!");
    }
    
}
package com.pb.demo6;
/*
 * 小猪类
 */
public class Pig extends Pet {

    @Override
    void toHospital() {
        System.out.println("小猪看病:打针、睡觉!");

    }
  public void sleep(){
      System.out.println("小猪要睡觉!");
  }
}
package com.pb.demo6;
/*
 * 宠物医生类
 */
public class Doctor {
    
    //医生治疗方法
    public void cure(Pet pet){ //将宠物传参
        
        if(pet.getHealth()<50){ //判断健康值小于50
            //调用看病的方法
            pet.toHospital();
            //将健康值设置为60,健康
            pet.setHealth(60);
            //判断是宠物类型
            if(pet instanceof Dog){
                //向下转型,强制类型转制
                Dog dog=(Dog)pet;
                //调用小狗自己的方法
                dog.run();
            }else if(pet instanceof Bird){
                //向下转型,强制类型转制
                Bird bird=(Bird)pet;
                //调用小鸟自己的方法
                bird.fly();
            }else if(pet instanceof Pig){
                //向下转型,强制类型转制
                Pig pig=(Pig)pet;
                //调用小猪自己的方法
                pig.sleep();
            }
        }
    }

}
package com.pb.demo6;
/*
 * 测试类
 */
public class Test {

    public static void main(String[] args) {
        //声明医生对象
        Doctor dc=new Doctor();
        //声明宠物对象为小鸟
       Pet brid=new Bird();
       //调用医生的治疗方法
       dc.cure(brid);
     //声明宠物对象为小狗
       Pet dog=new Dog();
     //调用医生的治疗方法
       dc.cure(dog);
     //声明宠物对象为小猪
       Pet pig=new Pig();
     //调用医生的治疗方法
       dc.cure(pig);
       
    }

}

结果:

小鸟看病:吃药、休息!
小鸟会飞!
小狗看病:打针、吃药!
小狗在地上跑!
小猪看病:打针、睡觉!
小猪要睡觉!

 五、父类做为形参

package com.pb.demo2;
/*
 * 商品类
 */
public class Goods {
    //打印商品价格方法
    public void printPrice(){
        System.out.println("打印商品价格");
    }
}

package com.pb.demo2;
/*
 * 食品类
 */
public class Foods extends Goods {

    @Override
    public void printPrice() {
        System.out.println("打印食品类的商品价格!");
    }

    
}
package com.pb.demo2;
/*
 * 电视类
 */
public class TVs extends Goods {

    @Override
    public void printPrice() {
    System.out.println("打印电视类商品价格!");
    }

    
}

测试类:

package com.pb.demo2;

public class Test {

    public static void main(String[] args) {
        //声明3 个商品价格
        Goods good=new Goods();
        Foods food=new Foods();
        TVs tvs=new TVs();
        //调用方法
        showPrice(good);
        showPrice(food);
        showPrice(tvs);

    }
    //显示商品价格方法
  static void showPrice(Goods good){
      good.printPrice();
  }
}

结果:

打印商品价格
打印食品类的商品价格!
打印电视类商品价格!
posted @ 2015-02-18 18:29  森林森  阅读(685)  评论(0编辑  收藏  举报