欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

学习笔记----Java多态

程序员文章站 2024-03-21 19:15:58
...
public class Animal {
    public void move(){
        System.out.println("动物跑");
    }
}
public class Cat extends Animal {                       ``
    @Override
    public void move() {
        System.out.println("猫跑");
    }

    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}
public class Bird extends Animal {
    @Override
    public void move() {
        System.out.println("鸟儿飞翔");
    }

    public void fly() {
        System.out.println("bird fly!");
    }
}

一: 关于Java语言中的多态语法机制

   1. Animal,Cat,Bird三个类之间的关系:
          Cat继承Animal
          Bird继承Animal
          Cat和Bird之间没有任何继承关系
          
   2. 以前编写的程序
          Animal  a1 = new  Animal();
          a1.move();   //动物跑
          
          Cat  c1 =  new  Cat(); 
          c1.move();  //猫跑
          c1.catchMouse(); //猫抓老鼠
          
   3. 使用多态语法机制
   		  Animal  a2 =  new  Cat();
   		  
   		  /**
   		   *   1. Animal和Cat之间存在继承关系,Animal是父类,Cat是子类
   		   *  
   		   *   2. Cat is a Animal[合理的]
   		   * 
   		   *   3. new Cat()创建的对象的类型是Cat,a2这个引用的数据类型是Animal,可见它们进行
   		       了类型转换,子类型转换成父类型,称为向上转型/upcasting,或自动类型转换
   		       
   		   *   4. Java中允许这种语法:父类型引用指向子类型对象
   		   */
			
		  a2.move();  //编译通过
		  
		  /**
		   * 1. java程序永远都分为编译阶段和运行阶段
		   * 
		   * 2. 先分析编译阶段,再分析运行阶段,编译无法通过,根本是无法运行的
		   * 
		   * 3. 编译阶段编译器检查a2这个引用的数据类型为Animal,由于Animal.class字节码当中 
		     有move()方法,所以编译通过了.这个过程称为静态绑定,编译阶段绑定.只有静态绑定成
		     功后才有后续的运行
		   *
		   * 4. 在程序运行阶段,JVM堆内存当中真实创建的对象是Cat对象,那么以下程序在运行阶
		     段一定会调用Cat对象的move()方法,此时发生了程序的动态绑定,运行阶段绑定
		     a2.move();  //输出的是"猫跑",而不是"动物跑". 
		     
		   * [注]:  Animal  a2 =  new  Cat();  
		            a2.move();
		            成员方法: 编译看左,运行看右。(成员方法存在'覆盖重写'编译和运行看的方向不一 
		            样)  
		   * 
		   * 5. 无论Cat类有没有重写move方法,运行阶段一定调用的是Cat对象的move方法,因为真
		        实对象就是Cat对象
		   * 
		   * 6. 父类型引用指向子类型对象这种机制导致程序在编译阶段绑定和运行阶段绑定两种  
		        不同的形态,这种机制可以成为一种多态语法机制
		   */

二: 使用多态的好处

   1. 降低程序的耦合度,提高程序的扩展力
  
   2. 核心:面向抽象编程,尽量不要面向具体编程
   
   3. 多态在实际开发中的作用:以下以主人喂养宠物为例
   
          分析:主人喂养宠物这个场景要实现需要进行类型的抽象;
            --主人[类]
            --主人可以喂养宠物,所以主人有喂养的这个动作
            --宠物[类]
            --宠物可以吃东西,所以宠物有吃东西的这个动作
            
		  不使用多态的代码实现:
		  
		  //主人[类]
		    public class Master{
		    	public void feed(Cat c){
		    		c.eat;
		    	}
		    }
		 
		  // 猫[类]  
		    public class Cat{
		    	public void eat(){
		    		System.out.println("小猫在吃鱼");
		    	}
		    }

			public class Test{
				public static void main(String[] args){
					//创建主人对象
					Master  zhangsan = new Master();
					//创建猫对象
					Cat tom = new Cat();
					//主人喂养猫
					zhangsan.feed(tom);   //小猫在吃鱼
				}
			}
			
	      问题:假如用户的需求发生变化了,主人不想养猫了,想养狗怎么办?	
				
			   此时需要增加一个Dog类
			   public class Dog{
			   		public void eat(){
			   			System.out.println("小狗正在啃骨头");
			   		}
			   }
			   同时Master类中也得加入新方法
			    public class Master{
		    		public void feed(Cat c){
		    			c.eat;
		    		}	
		    		public void feed(Dog d){	
		    			d.eat;
		    		}
		        }
		        
				public class Test{
					public static void main(String[] args){
						//创建主人对象
						Master  zhangsan = new Master();
						//创建猫对象
						Cat tom = new Cat();
						//主人喂养猫
						zhangsan.feed(tom);   //小猫在吃鱼
						//创建狗对象
						Dog d = new Dog();
						//主人喂小狗
						zhangsan.feed(d);  //小狗正在啃骨头
					}
				}
				
               [注]: 以上这种方式没有使用多态机制,存在的缺点:Msater类的扩展力很差,因为只要加       
                     入一个新的宠物,Master类就需要添加新的方法

		 使用多态机制的代码:

                //主人[类]
			    public class Master{
			    	public void feed(Pet p){
			    		p.eat;
			    	}
			    }
			    
			    public class Pet{
			    	public void eat(){
			    	}
			    } 
			    
			    public class Cat extends Pet{
			    	public void eat(){
			    		System.out.println("小猫在吃鱼");
			    	}
			    }
			    
			    public class Dog extends Pet{
			    	public void eat(){
			    		System.out.println("小狗在啃骨头");
			    	}
			    }
			    
			    public class Test{
			    	Master zhangsan = new Master();
			    	Pet cat = new Cat();
			    	Pet dog = new Dog();
			    	zhangsan.feed(cat);   //小猫在吃鱼
			   		zhangsan.feed(dog);  //小狗在啃骨头
			    }
			    //使用了多态后的程序就很健壮了,Master不再面向具体的Dog和Cat了.而是面向抽 
			    像的Pet