JAVA面向对象三大特征之多态性

什么是多态

多态,顾名思义,就是多种形态
在这里插入图片描述
比如小明是一个学生,那么小明也是一个人类,小明有多种形态,这就叫做对象的多态性。

多态的实现方法

多态一般分为两种

  1. 编译时多态
    编译时多态一般就是方法的重载,比如有三个同名不同参的方法名,当我用对象赋予不同参数条件时调用方法时,会根据不同的参数情况调用不同的方法。
public class Test {
	public void sum(int x,int y) {
		System.out.println(x+y);
	}
	public void sum(int x,int y,int z) {
		System.out.println(x+y+z);
	}

	public static void main(String[] args) {
		Test test = new Test();
		test.sum(2, 3);
		test.sum(3, 4,5);
	}

输出结果一个为5,一个为12。

  1. 运行时多态
    一般有两种方式

1、接口名 对象名=new 实现方法名();

public class Test2 implements Runnable{
	public void run() {	
	}
	public static void main(String[] args) {
		Runnable a = new Test2();
	}
}

这种使用接口实现的,我们重点了解另外一种方法。(两种方法差不多)
2、父类名 对象名 =new 父类名();//左父右子

public class Animal {
	public static void main(String[] args) {
		Animal cat = new Cat();
		Animal dog =new Dog();
		cat.eat();
		cat.run();
		
		dog.eat();
		dog.run();
//		dog.call();//错误写法!!!
		
	}
	public void eat() {
		System.out.println("animal is eating");
	}
	public void run() {
		System.out.println("animal is running");
	}

}
class Cat extends Animal{
	public void eat() {
		System.out.println("cat is eating");
	}
	public void run() {
		System.out.println("cat is running");
	}
}
class Dog extends Animal{
	public void eat() {
		System.out.println("dog is eating");
	}
	public void call() {
		System.out.println("dog id calling");
	}
	
}

在多态里面,我们有这样一句话
编译看左边,运行看右边
这句话什么意思呢,在这段代码里面。Cat类是有eat和run方法的,所以当cat对象调用的时候就是Cat类里的方法(即使Animal类也有这两个方法),但是Dog类只有eat方法没有run方法,所以当dog对象调用的时候,eat方法仍然是Dog类里面的方法,但是由于Dog类没有run方法,所以向上调用了Dog的父类Animal的run方法,这是运行看右边,即先调用右边的类的方法,没有则向上查找(new的是谁,先调用谁)。
那么还有半句话是什么呢,我们发现上面在·Dog类里面有一个方法为call,在Animal类里面没有,我们用dog对象调用的时候会发现报错,这是Animal里面没有这个方法导致的编译报错,所以这是编译看左边
以下是方法表便于理解
在这里插入图片描述
上面了解了调用方法的顺序,接下来我们补充一个小点,访问成员变量的顺序。
1、通过成员变量名直接访问(等号左边是谁就访问谁,没有向上找)

public class Test3 {
	public static void main(String[] args) {
		Fu a =new Zi();
		System.out.println(a.num);
//		System.out.println(a.num2);//错误写法!!!
	}
}
class Fu{
	int num=10;
}
class Zi extends Fu{
	int num =20;
	int num2=30;
}

在这段代码中输出是10,访问的fu类里的num(等号左边),但是我们如果访问num2就会发现报错,因为fu类里面没有这个变量。总结起来,可以这样说
编译看左边,运行也看左边
2、通过调用成员方法间接访问成员变量

public class Test3 {
	public static void main(String[] args) {
		Fu a =new Zi();
		a.num();
//		a.num2();//错误写法!!!
	}
}
class Fu{
	public void num() {
	   int num=10;
	   System.out.println(num);
	}
}
class Zi extends Fu{
	public void num() {
		   int num=20;
		   System.out.println(num);
		}
	public void num2() {
		   int num2=30;
		   System.out.println(num2);
		}
}

此种是通过调用方法实现的,上面提到的调用方法顺序一样,这里不再赘述。

多态的实现机制

简单讲下运行原理:
在Java里面,有一个叫JVM(Java虚拟机)的东西,这里面有一个专门功能分区叫方法区,这里面包含了所有实例的方法,它对应了有一个方法表,方法表里面存的是调用这个方法的地址。在程序运行的时候,通过invokeVirtual指令访问方法表调用方法,就实现了多态。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北极,南极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值