Java多态难点解析

Java多态


定义: 指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。

举例:一种事物的多种形态

  • 动物生物:人既是动物也是生物。
  • 牡丹=植物=生物:牡丹既是植物也是生物。

多态的几大必要条件:

  1. 必须要有继承关系才行。
  2. 完成继承的同时要有对父类的重写(重写和重载的区别在我的“java面向对象、内存、封装、变量、重载和重载讲解”这篇博客中也有介绍,感兴趣可以去了解一下。
  3. 有父类的指引变量指向子类的对象(这是java的多态在代码中的体现)。
    • 注意:这里所说的父类可以是直接的父类也可以是间接的父类。

这里我多插入一点知识:

  • 程序运行分为三个阶段:预编译、编译、运行。
    1. 预编译:程序打开的时候,活儿已经干完了,(预编译命令,#define)。
    2. 编译:从打开程序开始到点击左上角的三角形之前–只能识别“=”前面的引用类型,不会识别“=”后面的对象。
    3. 运行:是从点击三角形开始—真正的识别对象,对象开始干活。
      注意:有利于判断多态体系下当父类与子类定义了相同的属性时,对属性和方法的值的判断。
      1. 成员变量:编译的时候能不能访问看父类,运行时看父类。
      2. 成员方法:编译的时候看父类,运行时看子类。
      3. 静态方法:编译运行都看父类。

使用多态的方式:

  • 子类继承父类方式:
	class Animal2 {
		String name;
		public Animal2() {
			super();
			// TODO Auto-generated constructor stub
		}
		public Animal2(String name) {
			super();
			this.name = name;
		}
		public void eat() {
			// TODO Auto-generated method stub
			System.out.println("animal-eat");
		}
	}
	class Dog2 extends Animal2 {//子类继承了父类
		public void eat() {
			System.out.println("Dog-eat");
		}
		
		public void bark() {
			System.out.println("Dog-bark");
		}
	}
	
	class Cat2 extends Animal2 {//子类继承了父类
		public void eat() {
			System.out.println("Cat-eat");
		}
	}
	public static void main(String[] args) {
		
		//使用多态
		//用父类的引用指向子类的对象--这就是java的多态在代码中的体现
		//注意:这里所说的父类可以滴直接的父类也可以是间接的父类。
		
		Anima2 dog2 = new Dog2();
		dog2.eat();//首先通过Animal保存的地址找到Dog对象,Dog对象再调用show方法
					//不能通过的原因:在编译的时候识别的是引用类型,不识别对象,所以识别的只能是Animal中的方法。
	}
  • 实现接口的方式:
	interface Animal {
		void eat();
	}
	class Dog implements Animal {//实现了Animal接口
		public Dog() {
			super();
			// TODO Auto-generated constructor stub
		}
		
		public void eat() {
			System.out.println("Dog-eat");
		}
	}
	public static void main(String[] args) {
		//使用多态
		Anima dog = new Dog();
	}
  • 继承抽象类方式:类似于接口的方式

使用多态的优点:

  1. 可替换性(substitutability):多态对已存在代码具有可替换性。
  2. 可扩充性(extensibility):多态对代码具有可扩充性,增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。
  3. 接口性(interface-ability):多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
  4. 灵活性(flexibility):它在应用中体现了灵活多样的操作,提高了使用效率。
  5. 简化性(simplicity):多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

多态的两个重要的点:

  1. 前提:一定是多态下
  2. 两个点:
    1. 向上转型:相当于自定转型,由地类型向高类型。
      • 定义:将子类型转换为父类引用。
      • 注意:只是将引用类型转换,与=后没有关系。
    2. 向下转型:相当于强制类型转换,有高类型到低类型。
      • 定义:将父类的引用强制类型转换为子类的引用—调用子类特有的方法。
  3. 注意:
    • 转型是针对的引用不是类,不能试图用子类的引用指向父类的对象。
    • 不是多态的时候不存在向上转型和向下转型。

instanceof运算符:

  • 定义:确定全面的对象是不是后面的类或子类的对象,是返回true,不是返回false。
  • 前面和后面必须有继承的关系,如果没有会立刻报错。
  1. 一段实例代码:
	public class Demo9 {
		public static void main(String[] args) {
			Animal3 dog3 = new Dog3();
			Animal3 cat3 = new Cat3();
			feedAnimal(dog3);
		}
		
		public static void feedAnimal(Animal3 animal) {
			/*animal.eat();*/
			//调用特有的方法
			if(animal instanceof Dog3) {
				Dog3 dog3 = (Dog3) animal;
				dog3.bark();
			}
		}
	}
	class Animal3 {
		String name;
		public Animal3() {
			super();
			// TODO Auto-generated constructor stub
		}
		public Animal3(String name) {
			super();
			this.name = name;
		}
		public void eat() {
			// TODO Auto-generated method stub
			System.out.println("animal-eat");
		}
	}
	class Dog3 extends Animal3 {
		public void eat() {
			System.out.println("Dog-eat");
		}
		public void bark() {
			System.out.println("Dog-bark");
		}
	}
	class Cat3 extends Animal3 {
		public void eat() {
			System.out.println("Cat-eat");
		}
	}

总结:

java面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的,多态贯穿于java整个学习,多态就好比将电视从黑白带进了彩色时代。

你可能感兴趣的:(Java)