Java语言的多态性


  

引言:

Java三大特性之一多态性。

  1. 理解多态性:可以理解为一个事物的多种形态。

  2. 何为多态性:

    对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)

  3. 多态的使用:虚拟方法调用

    有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。

  4. 多态性的使用前提: ① 类的继承关系 ② 方法的重写

  5. 对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)

  6. 虚拟方法调用(多态情况下):
      子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。

    Person e = new Student();
    e.getInfo(); //调用Student类的getInfo()方法
  7. 编译时类型和运行时类型:
      编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。——动态绑定

  8. 有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。

  9. 如何调用子类所特有的属性和方法:

    向下转型:使用强制数据类型转换(注:使用强转时,可能出现ClassCastException的异常),记得使用**”instanceof”**关键字。a instanceof A:判断对象a是否是类A的实例

    Person p = new Man()
    Man m = (Man) p;
    Woman w = (Woman) p;
    w.goShopping();//编译不报错,运行时可能会出现ClassCastException的异常
    if (p instanceof Woman){
    Woman w1 = (Woman)p;
       w1.goShopping();
    }
public class AnimalTest {
	public static void main(String[] args) {
		AnimalTest test = new AnimalTest();
		test.func(new Dog());

		test.func(new Cat());
	}

	public void func(Animal animal){
		animal.eat();
		animal.shout();

		if(animal instanceof Dog){
			Dog d = (Dog)animal;
			d.watchDoor();
		}
	}

//	public void func(Dog dog){
//		dog.eat();
//		dog.shout();
//	}
//	public void func(Cat cat){
//		cat.eat();
//		cat.shout();
//	}
}

class Animal{
	public void eat(){
		System.out.println("动物:进食");
	}

	public void shout(){
		System.out.println("动物:叫");
	}
}

class Dog extends Animal{
	public void eat(){
		System.out.println("狗吃骨头");
	}

	public void shout(){
		System.out.println("汪!汪!汪!");
	}

	public void watchDoor(){
		System.out.println("看门");
	}
}
class Cat extends Animal{
	public void eat(){
		System.out.println("猫吃鱼");
	}

	public void shout(){
		System.out.println("喵!喵!喵!");
	}
}
import java.util.Random;

//面试题:多态是编译时行为还是运行时行为?
//证明如下:
class Animal  {
	protected void eat() {
		System.out.println("animal eat food");
	}
}

class Cat  extends Animal  {
	protected void eat() {
		System.out.println("cat eat fish");
	}
}

class Dog  extends Animal  {
	public void eat() {
		System.out.println("Dog eat bone");
	}
}

class Sheep  extends Animal  {
	public void eat() {
		System.out.println("Sheep eat grass");
	}
}

public class InterviewTest {
	public static Animal  getInstance(int key) {
		switch (key) {
		case 0:
			return new Cat ();
		case 1:
			return new Dog ();
		default:
			return new Sheep ();
		}
	}

	public static void main(String[] args) {
		int key = new Random().nextInt(3);
		System.out.println(key);
		Animal  animal = getInstance(key);
		animal.eat();
	}
}

文章作者: YangChongZhi
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 YangChongZhi !
评论
 上一篇
Java中的Object类 Java中的Object类
   引言: java.lang.Object类相关知识点说明 Object类是所有Java类的根父类 如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类 Object类中的功能(属
2021-01-01
下一篇 
Java子类对象实例化的全过程 Java子类对象实例化的全过程
   引言: Java中子类对象的实例化全过程分析。 从结果上来看:(继承性) 子类继承父类以后,就获取了父类中声明的属性或方法。 创建子类的对象,在堆空间中,就会加载所有父类中声明的属性。 从过程上来看:   当我们通过子
2020-12-31
  目录