JAVA入门级教学之(多态)


 * 你本身就该就你爹叫爹,你让你爹叫你爹就是强制认做爹
 * 
 * 关于java语言汇总的多态语法机制:【只是多态的基础语法,多态的作用后续说明】
 * 
 *     1.多态中设计的几个概念
 * 
 *         *向上转型(upcasting)
 *             子类型转父类型:自动类型转换
 *         
 *         *向下转型(downcasting)
 *             父类型转子类型:强制类型转换【需要加强制类型转换符】
 * 
 *     2.无论是向上转型还是向下转型,两种类型之间必须存在继承关系
 * 
 *       *没有继承关系,程序是无法编译通过的
public class Test {

    public static void main(String[] args) {
        
        //使用多态语法机制
        /*
         * 1.Animal和cat之间存在继承关系,Animal是父类,Cat是子类
         * 
         * 2.Cat is a Animal是合理的
         * 
         * 3.new Cat() 创建的对象类型是Cat,a2这个引用的数据类型是Animal,可见
         *   它们进行了类型转换:子类型转换成父类型,称为向上转型/upcasting,称为自动类型转换
         *   
         * 4.java中允许这种语法:父类型引用指向子类型对象  
         */
        Animal a2=new Cat();
        /*
         * 1.java程序永远都分为编辑阶段和运行阶段
         * 
         * 2.先分析编译阶段,再分析运行阶段,如果编译无法通过,根本是无法运行的
         * 
         * 3.编译阶段编译器检查a2这个引用的数据类型为Animal,由于Animal.class
         *      的字节码中有move()方法,所以编译通过了。这个过程我们称为静态绑定【编译阶段绑定】
         *      只有静态绑定成功后才有后续的运行
         * 
         * 4.在程序运行阶段,JVM堆内存中真实创建的对象是Cat对象,那么以下程序在运行阶段
         *      一定会调用Cat对象的move()方法,此时发生了程序的动态绑定【运行阶段绑定】
         *     
         * 5.无论是Cat类中有没有重写move方法,运行阶段一定调用的是Cat对象的move方法,因为
         *      底层真实的对象就是Cat对象
         * 
         * 6.父类型引用指向子类型对象这种机制导致程序存在编译阶段和运行阶段绑定两种不同的形态
         *   这种机制就叫做多态语法机制
         */

--------------------------------------------------------------------------------------------------------------------------------------------------------------- 

新建一个动物类 

package com.lbj.javase11;

public class Animal {
	  public void move(){
		  System.out.println("动物都可以移动");
	  }
	}

新建一个鸟类继承动物类 

package com.lbj.javase11;

public class Bird extends Animal {
	 public void move(){
		  System.out.println("鸟会飞");
	  }
	 //子类特有的行为
	 public void fly(){
		 System.out.println("fly method");
	 }
}

 新建一个猫类继承动物类

package com.lbj.javase11;

public class Cat extends Animal{
	//重写父类中继承过来的方法
	 public void move(){
		  System.out.println("猫会走猫步");
	  }
	 
	 //不是父类中继承过来的方法
	 //这个方法是子类对象特有的行为【不是说所有的动物都能抓老鼠】
	 public void catchMouse(){
		 System.out.println("猫抓老鼠");
	 }
}

 新建一个测试类:

package com.lbj.javase11;
/**
 * 你本身就该就你爹叫爹,你让你爹叫你爹就是强制认做爹
 * 
 * 关于java语言汇总的多态语法机制:【只是多态的基础语法,多态的作用后续说明】
 * 
 * 	1.多态中设计的几个概念
 * 
 * 		*向上转型(upcasting)
 * 			子类型转父类型:自动类型转换
 * 		
 * 		*向下转型(downcasting)
 * 			父类型转子类型:强制类型转换【需要加强制类型转换符】
 * 
 * 	2.无论是向上转型还是向下转型,两种类型之间必须存在继承关系
 * 
 * 	  *没有继承关系,程序是无法编译通过的
 * @author 14811
 *
 *
 *
 */
public class Test {

	public static void main(String[] args) {
		
		//使用多态语法机制
		/*
		 * 1.Animal和cat之间存在继承关系,Animal是父类,Cat是子类
		 * 
		 * 2.Cat is a Animal是合理的
		 * 
		 * 3.new Cat() 创建的对象类型是Cat,a2这个引用的数据类型是Animal,可见
		 *   它们进行了类型转换:子类型转换成父类型,称为向上转型/upcasting,称为自动类型转换
		 *   
		 * 4.java中允许这种语法:父类型引用指向子类型对象  
		 */
		Animal a2=new Cat();
		/*
		 * 1.java程序永远都分为编辑阶段和运行阶段
		 * 
		 * 2.先分析编译阶段,再分析运行阶段,如果编译无法通过,根本是无法运行的
		 * 
		 * 3.编译阶段编译器检查a2这个引用的数据类型为Animal,由于Animal.class
		 * 	 的字节码中有move()方法,所以编译通过了。这个过程我们称为静态绑定【编译阶段绑定】
		 * 	 只有静态绑定成功后才有后续的运行
		 * 
		 * 4.在程序运行阶段,JVM堆内存中真实创建的对象是Cat对象,那么以下程序在运行阶段
		 * 	 一定会调用Cat对象的move()方法,此时发生了程序的动态绑定【运行阶段绑定】
		 * 	
		 * 5.无论是Cat类中有没有重写move方法,运行阶段一定调用的是Cat对象的move方法,因为
		 * 	 底层真实的对象就是Cat对象
		 * 
		 * 6.父类型引用指向子类型对象这种机制导致程序存在编译阶段和运行阶段绑定两种不同的形态
		 *   这种机制就叫做多态语法机制
		 */
		a2.move();
		
		/*
		 * 分析以下程序为什么不能调用:
		 * 	因为编译阶段编译器检查到a2的类型是Animal类型
		 *  从Animal.class字节码文件中查找catchMouse()方法,最终没有找到该方法
		 *  导致静态绑定失败,没有绑定成功,也就是说编译失败了,更别说运行了
		 */
		//a2.catchMouse();
		/*
		 *	假设想让以上的对象执行catchMouse()方法 ,怎么办?
		 *		a2是无法直接调用的,因为a2的类型Animal,Animal中没有catchMouse()方法
		 *		我们可以将a2强制类型转换成Cat类型
		 *		a2的类型是Animal(父类),转换成Cat类型(子类),被称为向下转型/downCasting/强制类型转换
		 *		
		 *	注:向下转型也需要两种类型之间必须有继承关系,不然编译报错。强制类型转换需要加强制类型转换符
		 *
		 *	什么时候需要使用向下转型呢?
		 *		当调用的方法是子类型中特有的,在父类型中不存在,必须进行向下转型
		 */
		Cat c2=(Cat)a2;
		
		c2.catchMouse();
	
		
		//----------------------------------
		Animal a3=new Bird();
		
		/*
		 * 1.以下程序编译是没有问题的,因为编译器检查到a3的数据类型是Animal
		 * 	 Animal和Cat之间存在继承关系,并且Animal是父类型,Cat是子类型
		 * 	 父类型转换成子类型叫做向下转型,语法合格
		 * 
		 * 2.虽然程序通过了,但是程序在运行阶段会出现异常,因为JVM堆内存中
		 * 	 真实存在的对象是Bird类型,Bird对象无法转换成Cat对象,因为两种
		 *   类型之间不存在任何继承关系,此时出现了著名的异常
		 *   java.lang.ClassCastException:
		 *   类型转换异常,这种异常总是在"向下转型"的时候会发生
		 */
		
		//Cat c3=(Cat)a3;
		
		//--------------------------------------------
		/*
		 * 1.以上异常只有在强制类型转换的时候会发生,也就是说"向下转型"存在隐患(编译通过了,但是运行出错了)
		 * 
		 * 2.向上转型只要编译通过,运行一定不会出问题
		 * 
		 * 3.向下转型编译通过,运行可能错误
		 * 
		 * 4.怎么避免向下转型出现 java.lang.ClassCastException:呢?
		 * 	 -使用instanceof运算符可以避免出现以上的异常
		 * 
		 * 5.instanceof运算符怎么用?
		 * 	 -5.1语法格式:
		 * 		(引用名 instanceof 数据类型名)
		 * 
		 *   -5.2以上运算符的执行结果类型是布尔类型,结果可能是true/false
		 * 
		 * 	 -5.3关于运算结果true/false
		 * 		假设:(a instanceof Animal)
		 * 		true表示:
		 * 			a这个引用指向的对象是一个Animal类型
		 * 		false表示:
		 * 			a这个引用指向的对象不是一个Animal类型
		 * 
		 * 6.java规范中要求:在进行强制类型转换之前,建议采用 instancsof运算符进行判断,避免异常的发生
		 */
		
		//当a3引用指向的对象却是是一个Cat的时候【等同于:a3 是Cat的实例吗? 】{
//			Cat c3=(Cat)a3;
		//}
		if(a3 instanceof Cat){
			Cat c3=(Cat)a3;//这时候编译器就会检测
		}else if(a3 instanceof Bird){//a3确实是Bird类的,所以再强制转换就会成功
			Bird b2=(Bird)a3;
			b2.fly();
		}
		 
	}

}



发布了81 篇原创文章 · 获赞 3 · 访问量 2453

猜你喜欢

转载自blog.csdn.net/LBJ8888888/article/details/104528551