详述多态

详述多态

1、什么是多态?
在了解什么是多态之前,我们先来认识一下上转型对象。子类实例化的对象赋值给父类声明变量,则该对象称为上转型对象,这个过程称为对象上转型,对应于数据类型转换中的自动类型转换例如:double price = 10;
父类类型(比如Mammal)的变量(比如mammal)指向子类创建的对象这个子类创建的对象也称为上转型对象,使用该变量调用父类中一个被子类重写的方法(比如move方法),则父类中的方法呈现出不同的行为特征,这就是多态。

public class Mammal {
	public void Move() {
		System.out.println("正在移动......");
	}
	public class Whale extends Mammal{
	@Override
	public void Move() {
		System.out.println("靠鱼鳍移动......");
	}
}
public class Earth {
	public static void main(String[] args) {
		Whale whale = new Whale();
		whale.Move();//当子类对象调用重写后的方法,调用的是子类重写后的方法
		Mammal mammal = new Whale();//子类实例化的对象赋值给父类声明变量,则该对象称为上转型对象,这个过程称为对象上转型,对应于数据类型转换中的自动类型转换。new Whale()是上转型对象,父类类型变量指向子类创建的对象,等号左边编译时类型,右边运行时类型
		mammal.Move();
	}
}

在这里插入图片描述
2、怎么出现多态?
Java引用变量有两种类型,分别是编译时类型和运行时类型:编译时类型由声明该变量时使用的类型决定;运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓多态。
上转型对象调用被重写的方法,调用的是重写后的方法。因为mammal是父类类型变量但指向子类创建的对象,所以变量mammal编译时类型是父类类型Mammal,运行时类型是子类类型Whale。
3、上转型对象不能调用子类新增的方法和属性

public class Mammal {
	public void Move() {
		System.out.println("正在移动......");
	}
}
public class Whale extends Mammal{
	double weight = 10000;
	@Override
	public void Move() {
		System.out.println("靠鱼鳍移动......");
	}
	public void Breath() {
		System.out.println("正在呼吸");
	}
}
public class Earth {
	public static void main(String[] args) {
		Mammal mammal = new Whale();//自动类型转换(对象上转型)new Whale()是上转型对象,父类类型变量指向				    子类创建的对象,等号左边编译时类型,右边运行时类型
		mammal.Move();//两个状态:表面上调用的是父类的方法,但执行时由于mammal存的是子类创建的对象,所以执行时执行的是子类中方法
		mammal.Breath();//上转型对象不能调用子类新增方法和属性
    	mammal.weight = 12000
	}
}

在这里插入图片描述
因为mammal编译时类型是父类类型,而父类中没有属性weight和方法breath(),所以程序在编译时就会报错。
4、怎么利用上转型对象调用新增的属性和方法?
对象上转型利用下转型调用新增的属性和方法,下转型的前提上转型。

public class Mammal {
	public void Move() {
		System.out.println("正在移动......");
	}
}
public class Whale extends Mammal{
	double weight ;
	@Override
	public void Move() {
		System.out.println("靠鱼鳍移动......");
	}
	public void Breath() {
		System.out.println("正在呼吸");
	}
}
public class Earth {
	public static void main(String[] args) {
		Mammal mammal = new Whale();
		//上转型对象如何调用新增的属性和方法,使用下转型
		Whale whale = (Whale)mammal;
		whale.Breath();
		whale.weight = 12333.255;
		System.out.println(whale.weight);
//		Mammal mammal = new Mammal();
//		Whale whale = (Whale)mammal;//不能称为下转型,因为mammal不是上转型对象,下转型前提是先出现上转型对象
	}
}

在这里插入图片描述

程序中的注释符去掉将会报错 Mammal mammal = new Mammal();
Whale whale = (Whale)mammal;
因为new Mammal()不是上转型对象,无法进行下转型。
5、上转型对象调用被子类覆盖的属性时,调用的是父类的属性

public class Mammal {
	public String weight = "1t";
	public void Move() {
		System.out.println("正在移动......");
	}
}
public class Whale extends Mammal{
	double weight = 1000;
	@Override
	public void Move() {
		System.out.println("靠鱼鳍移动......");
	}
	public void Breath() {
		System.out.println("正在呼吸");
	}
}
public class Earth {
	public static void main(String[] args) {
		Mammal mammal = new Whale();
 		System.out.println(new Whale().weight);
 		System.out.println(mammal.weight);//上转型对象调用被子类覆盖的属性,调用的是父类的属性
	}
}

在这里插入图片描述
总而言之,上转型对象调用父类的方法,如果方法已被子类重写,则表现为子类的行为特征,否则表现为父类的行为特征。
上转型对象调用父类的成员变量,无论该成员变量是否被子类覆盖,使用的都是父类的成员变量

6、在多态的前提下,父类中被子类重写的方法没有必要有方法体
父类中没有方法体的方法称为抽象方法,只要有一个抽象方法的类称为抽象类,所有的方法都是抽象方法的类称为接口。

public class Mammal {
		public void Move() {
		
	}
}
public class Whale extends Mammal{
	@Override
	public void Move() {
		System.out.println("靠鱼鳍移动......");
	}
}
public class Earth {
	public static void main(String[] args) {
		Whale whale = new Whale();
		whale.Move();
	}
}

在这里插入图片描述
注意:
如果编译时类型和运行时类型相同,则一定不会出现多态
如果编译时类型和运行时类型不同,也不一定会出现多态

第一句话很好理解,第二句话的意思是及时编译时类型和运行时类型不同,上转型对象调用的方法也不一定被重写,这时,也不会出现多态。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值