Bootstrap

java 面向对象的特征之三 多态 java instanceof 向上转型 向下转型

1. 多态性,是面向对象中最重要的概念,在java中有两种体现:

  1. 子类方法的重写(overwrite)和同类方法的重载(overload)
  2. 对象的多态性===可以直接应用在抽象类和接口上
  3. 理解:一个事物的多种表现形式

2. java引用变量的两个类型

  1. 编译时类型:编译时类型由声明该变量的时候使用的类型决定
  2. 运行时类型:运行时类型由实际赋值给变量的对象决定
  • 注:
  • 若编译时类型和运行时类型不一致,就出现了多态性(Polymorphism)

3. 子类对象的多态性的使用前提

  1. 要有类的继承
  2. 子类对父类方法的重写(构造器也是一样的概念)

4. 子类对象的多态性(向上转型)

  1. 父类的 引用指向子类对象 或者是子类对象实体付给父类的引用
  2. 以父类的身份运行子类的实体又称向上转型
  3. 虚拟方法盗用:通过父类引用指向子类的对象实体,当调用方法时,实际是执行子类重写父类的方法
  4. 向上转型肯定是可以转的,可以理解为:女人一定人,但人不一定是女人。
  5. demo
Person p1 = new Man();

5. 程序运行分为编译状态和运行状态

  1. 对于多态性来说,编译的时候,“看左边”,将此引用变量理解为父类的类型
  2. 运行时,“看右边”,关注于真正对象的实体,子类的对象,那么执行的方法就是子类重写的。

6.向下转型(需注意的点)

  1. 格式为 父类实例指向子类引用
  2. 需要用到强制转换,向上转型则为自动转换
  3. 若方法为子类特有的,则编译无法通过,(无法调用,因为引用指向了父类,而父类并没有这个方法)
  4. demo
Person p2 = new Women();
p2.eat();
p2.walk();
//p2.shopping();//编译出错

自动类型转换或者强制类型转换

7. 向下转型正确使用 最好通过 instanceof

  1. 格式:对象a instanceof 类A
  2. 含义:判断对象a是否是类A的一个实例,是的话返回true,否则,返回false。
  3. 若a是A类的实例,那么a也一定是A类的父类的实例
  4. dome
if(p1 instanceof Man) {
	Man m1 = (Man)p1;
	m1.entertainment();
}

if(p1 instanceof Person) {
	System.out.println("你好");
}

8.类的属性无多态性

  1. 父类和子类出现多个同名的属性
  2. 引用是谁,即属性就是谁的属性
  3. demo
Person p1 = new Man();
p1.id;//为父类引用的id属性

9.dome

public class TestPerson {
	public static void main(String[] args) {
		Person p  = new Person();
		p.eat();
		p.walk();
		
		Man m = new Man();
		m.eat();
		m.walk();
		
		
		//子类对象的多态性:父类的 引用指向子类对象   
		//或者是子类对象实体付给父类的引用
		Person p1 = new Man();//以父类的身份运行子类的实体 //向上转型
		//虚拟方法盗用:通过父类引用指向子类的对象实体,当调用方法时,实际是执行子类重写父类的方法
		p1.eat();
		p1.walk();//调用子类的方法
		
		Person p2 = new Women();
		p2.eat();
		p2.walk();
//		p2.shopping(); //无法调用,因为引用指向了父类,而父类并没有这个方法
	
		Women w = (Women)p2;//向下转型,使用强制转换符()
		w.shopping();
		
		//出现异常 :java.lang.ClassCastException
//		Women w1 = (Women)p1;//编译时可以通过,但运行时会报错
//		w1.shopping();
		
		
		
//		Women w2 = (Women)new Man();编译时就出错
		
		//向下转型正确使用 最好通过 instanceof
		if(p1 instanceof Women) {
			Women w1 = (Women)p1;
			w1.shopping();
		}
		//instanceof 
		//格式:对象a instanceof 类A :判断对象a是否是类A的一个实例,是的话返回true,否则,返回false。
		//若a是A类的实例,那么a也一定是A类的父类的实例
		if(p1 instanceof Man) {
			Man m1 = (Man)p1;
			m1.entertainment();
		}
		
		if(p1 instanceof Person) {
			System.out.println("你好");
		}
	}
}
public class Man extends Person {
	private boolean smoking;
	...
	public  void entertainment() {
		System.out.println("男人请客");
	}
}

public class Person {
	private String name;
	private int age;
	...
	public void walk() {
		System.out.println("人走路");
	}
	public void eat() {
		System.out.println("人吃放");
	}
}

public class Women extends Person{
	private boolean isBeauty;
	...
	public void walk() {
		System.out.println("女人人走路");
	}
	public void eat() {
		System.out.println("女人吃放");
	}	
	public void shopping(){
		System.out.println("女人爱购物");
	}
}

10.多态性的应用举例

public class TestAnimal {
	public static void main(String[] args) {
		//没有多态的情况,想调用Dog的方法
		//只能新建func(Dog a)方法
		//但有多态的时候,可以直接test.func(new Dog());,相当于Animal a = new Dog();
		TestAnimal test = new TestAnimal();
		test.func(new Animal());
		test.func(new Dog());
		test.func(new Cat());
	}
	public void func(Animal a) {
		a.eat();
		a.jump();
		
		//若想调用子类特有的方法
		//使用 instanceof
		if(a instanceof Dog) {
			Dog d = (Dog)a;
			d.wang();
		}
		if(a instanceof Cat) {
			Cat c = (Cat)a;
			c.catchMouse();
		}
		
	}
	
	public void func(Dog a) {
		a.eat();
		a.jump();
	}
}
class Animal{
	String name;
	int age;
	public void eat() {
		System.out.println("进食");
	}
	public void jump() {
		System.out.println("跳");
	}
}
class Dog extends Animal{
	
	public void eat() {
		System.out.println("狗吃食");
	}
	public void jump() {
		System.out.println("狗急跳墙");
	}
	public void wang(){
		System.out.println("汪汪叫");
	}
}
class Cat extends Animal{
	public void eat() {
		System.out.println("狗吃鱼");
	}
	public void jump() {
		System.out.println("猫跳");
	}
	public void catchMouse() {
		System.out.println("猫捉老鼠");
	}
}
;