JAVA零基础小白自学日志——第十八天


今日提要:多态(脑袋都要大了)

1.多态的定义

[1].早期绑定(编译期多态)

定义:指在程序编译阶段根据对象的静态类型来确定调用哪个方法。在编译期多态中,编译器根据对象的静态类型来决定调用哪个方法,而不是根据对象的实际类型来决定调用哪个方法。这种多态是在编译时期就确定的。
要多变态有多变态,嗯嗯,简称多态
其实也没有多神秘,其实就是方法重载;方法重载发生在编译阶段,不依赖对象的实际运行情况,灵活性差,但是可以提高程序的效率和安全性;
不过我们今天和以后要说的多态其实是后期绑定,不是一开始绑上这个,是后面才绑上的那个;

[2].后期绑定(运行时多态)

定义:它允许一个对象在不同的上下文中表现出不同的行为。具体来说,多态是指在一个类的继承关系中,子类可以对父类的方法进行重写,从而使得在调用这些方法时,根据实际对象的类型来决定调用的是哪个类的方法。
其实就是说说继承关系中的方法重写;我不明白为什么要把这么简单的事情用那么复杂的概念定义出来,难道是怕说错了,负什么什么责任么?

2.为什么要聊运行时多态

后面没有特别说明的多态,都指的是运行时多态,它为什么这么重要,因为一个非常简单的原因,运行时多态可以让我们的代码具有更高的可读性和可维护性,代码的调用只关注接口而不用去关注具体实现,也就是说我们的代码能够更模块化,从而可以降低代码的耦合度(这句不像人话的人话,以后慢慢解释);

3.多态的表现形式(已经说了,没有特别说明,咱们说的多态就是运行时多态)

[1].继承关系方法重写

这是多态的核心内容
几个要点:

  • 继承关系,继承关系,继承关系,重要的事情说三遍;
  • 子类父类定义的方法名必须相同;
  • 参数列表必须相同;
  • 返回值类型必须相同;
  • 范围修饰符可以扩大或者相同:public > protected > default;
    看段代码更好理解
class Animal{
	protected void roam () {
		System.out.println("动物在闲逛");
		
	}
}	

class Wolf extends Animal{
	public void roam() {
		System.out.println("狼在原地盘桓");
	}
}

class Tiger extends Animal{
	void roam() {//这个是错误的
		System.out.println("老虎在奔跑");
	}
}

父类方法是protected void roam (),子类狼的重写方法public void roam()是正确的,子类老虎的重写方法void roam()是错误的,因为默认访问范围权限小于父类的方法的访问范围权限;
现在可能你就要问了,为啥访问范围权限不提private呢?记住了,private(私有)不让继承,不让继承
现在来看一个完整的重写:

class Animal{
	protected void roam () {
		System.out.println("动物在闲逛");		
	}
}	

class Wolf extends Animal{
	public void roam() {
		System.out.println("狼在原地盘桓");
	}
}

class Tiger extends Animal{
	public void roam() {
		System.out.println("老虎在奔跑");
	}
}
public class TestOne {

	public static void main(String[] args) {
		Animal a = new Animal();
		Animal a1 = new Wolf();
		Animal a2 = new Tiger();

		a.roam();
		a1.roam();
		a2.roam();
	}
}

输出结果:

动物在闲逛
狼在原地盘桓
老虎在奔跑

这就是所谓的多态,是不是很容易理解了,不过理解不是重点,是理解以后的应用

[2].一些简单的应用实例

来,上盘代码:

class Animal{
	protected void roam () {
		System.out.println("动物在闲逛");
		
	}
}	

class Wolf extends Animal{
	public void roam() {
		System.out.println("狼在原地盘桓");
	}
}

class Tiger extends Animal{
	public void roam() {
		System.out.println("老虎在奔跑");
	}
}
public class TestOne {

	public static void main(String[] args) {
		Animal[] aa = new Animal[2];
		aa[0] = new Wolf();
		aa[1] = new Tiger();
		for (Animal dd : aa){
		    dd.roam();
		{		
	}

}

看看这个Animal[] aa = new Animal[2];眼熟不?不眼熟?再来看看这个String[] xx = new String[2];多态数组也是引用数组哦,你可以当一个数组来使用
上面那段代码的输出结果:

狼在原地盘桓
老虎在奔跑

如果这时我们需要一个方法要调用不同的对象,需要把不同的对象当做参数来用,我们就可以写public void xxxx(Animal a){......}这么个方法
来段代码

class Animal{
	protected void roam () {
		System.out.println("动物在闲逛");
		
	}
}	

class Wolf extends Animal{
	public void roam() {
		System.out.println("狼在原地盘桓");
	}
}

class Tiger extends Animal{
	public void roam() {
		System.out.println("老虎在奔跑");
	}
}

class Eat{
	public void eatUp(Animal a) {
		System.out.print("吃完饭以后,");
		a.roam();
		
	}
}
public class TestOne {

	public static void main(String[] args) {
		Eat ss = new Eat();		
		Animal a = new Animal();
		Animal a1 = new Wolf();
		Animal a2 = new Tiger();
		ss.eatUp(a1);
		ss.eatUp(a2);
		
	}
}

输出结果:

吃完饭以后,狼在原地盘桓
吃完饭以后,老虎在奔跑

多态决定了,你可以根据不同的对象,输出不同的结果,这样可以让我们的代码灵活性更高,无论再增加多少个子类,都可以正确的输出,这就是意义所在了,Eat类根本不用考虑哪些子类是后加的还是原来就有的,都一样可以执行;

多态就说到这里,多态最直接的地方就是我们可以模块化设计自己的代码,增加代码的可扩展性和灵活性,还有就是模块的复用性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值