*多态:1.一个对象在不同情况下的多种状态。 


      2.父类型定义引用,引用执行子类型的堆空间。 


   *多态前提:两个对象之间一定要有关系 即 

      

     1.继承关系; 


     2.实现关系(接口)。 


   *分析对象状态: 


     1.父类有,子类无:调用的是父类的方法; 

      

     2.父类有,子类也有,即子类重写了父类的方法:调用的是子类的方法; 
    3.父类无,子类有:编译出错。
*方法的多态总结:
     编译看左边,运行看右边!

   *变量的多态总结:
     编译看左边,运行还看左边!
 


   *如果不确定父类型的引用指向何种类型,则向下转换时,一定要判断类型 


     如 //如果不确定父类型的引用指向何种类型,则向下转换时,一定要判断类型 

         if(fd instanceof Fruits) {//提高了程序的健壮性 

             Fruits fruits = (Fruits)fd; 

             fruits.eated(); 

         } 

      

         /*如果不进行判断直接像下两行这样写 

          Fruits fruits = (Fruits)food1; 

          fruits.eated(); 

          会报java.lang.ClassCastException这个类型转换异常! 

         */ 


   *多态的优点:提高了程序的扩展性 


  *多态的缺点:向下转换时容易出现运行异常,因此为了提高程序的健壮性,向下转换时,务必要判断类型。
 
 

(完整程序,可运行)具体代码测试如下:
package polymorphismDemo;

 public class FoodDemo {
     public static void main(String[] args) {
         //父类型定义引用,引用执行子类型的堆空间,就叫多态。
         Food food = new InstantNoodles();
         //Food food = new Fruits();//注释上一行,运行此行,下面的输出结果会不同
         food.eated();//输出泡面要用开水泡着吃!
         food.storage();//输出泡面可以被存储很久!
         
         System.out.println("-------下面是向下转换的内容--------");
         
         Food fd = new InstantNoodles(30,"有嚼劲","乳黄色","小袋");
         
         //如果不确定父类型的引用指向何种类型,则向下转换时,一定要判断类型
         if(fd instanceof Fruits) {//提高了程序的健壮性
             Fruits fruits = (Fruits)fd;
             fruits.eated();
         }else if(fd instanceof InstantNoodles){
             System.out.println("类型匹配InstantNoodles,运行输出如下:");
             InstantNoodles isn = (InstantNoodles)fd;
             isn.eated();
             isn.storage();
         }else {
             System.out.println("没有匹配的类型!");
         }

         /*如果不进行判断直接像下两行这样写
          Fruits fruits = (Fruits)food1;
          fruits.eated();
          会报java.lang.ClassCastException这个类型转换异常!
         */

     }
     
 } class Food{
     private int shelfLife;//食物保质期
     private String taste;//食物口味
     private String color;//食物颜色
     
     Food(){//无参数的构造方法
         this.shelfLife = shelfLife;
         this.taste = taste;
         this.color = color;
     }
     
     Food(int shelfLife,String taste,String color){//有参数的构造方法
         this.shelfLife = shelfLife;
         this.taste = taste;
         this.color = color;
     }
     
     public void eated() {
         System.out.println("食物可以被吃!");
     }
     public void storage() {
         System.out.println("食物可以被存储!");
     }
     
 }

 class InstantNoodles extends Food{//泡面类
     private String size;//泡面有大小袋之分
     InstantNoodles(){
         this.size = size;
     }
     
     //有参数的构造方法
     InstantNoodles(int shelfLife,String taste,String color,String size){
         super(shelfLife,taste,color);
         this.size = size;
     }
     
     public void eated() {
         System.out.println("泡面要用开水泡着吃!");
     }
     
     public void storage() {
         System.out.println("泡面可以被存储很久!");
     }
     
 }

 class Fruits extends Food{
     private String season;//水果成熟有季节
     Fruits(){//无参数的构造函数
         this.season = season;
     }
     //有参数的构造函数
     Fruits(int shelfLife,String taste,String color,String season){
         super(shelfLife,taste,color);
         this.season = season;
     }
     
     public void eated() {
         System.out.println("水果可以直接吃!");
     }
     
     public void storage() {
         System.out.println("水果不可以被存储很久!");
     }
     
 }