Java语言中的多态

多态的定义

在这里插入图片描述

public class Test{
	public static void main(String[] args) {
	Mammal mammal1=new Whale();//自动类型转换:父类类型的变量指向其子类创建的对象 对象上转型  		new Whale()上转型对象,类似于double  price =9;由int 类型转化为double类型
	mammal1.move();
	Mammal mammal2=new Bat();
	mammal2.move();两个状态:表面调用的是父类的方法因为创建的对象为mammal中的方法;但是执行时由于mammal2存的是子类创建的对象(存储的为子类的地址,jvm根据地址找到编译运行时的对象),所以执行时执行的是子类中的方法
  
	}
}	

分析:当把子类创建的对象直接赋给父类引用类型时,例如上例Test main方法中“Mammal mammal1 = new Whale();”, mammal1引用变量的编译时类型是Mammal,运行时类型是Whale,当程序运行时,该引用变量mammal1调用父类中被子类重写的方法时,其方法行为表现的是子类重写该方法后的行为特征,而不是父类方法的行为特征。

父类类型(比如Mammal)的变量(比如mammal1)指向子类创建的对象,使用该变量调用父类中一个被子类重写的方法(比如move方法),则父类中的方法呈现出不同的行为特征,这就是多态。

在这里插入图片描述

出现多态的原因
Java引用变量有两种类型,分别是编译时类型运行时类型:编译时类型由声明该变量时使用的类型决定;运行时类型由实际赋给该变量的对象。如果编译时类型和运行时类型不一致,就可能出现所谓多态。

**编译时类型:**决定了其所修饰的变量名只能调用编译时类型中定义的或其继承过来方法。
**运行时类型:**决定了编译时类型修饰的变量名所调用的方法在程序执行过程中最终调用调用的方法。

注意:如果编译时类型和运行时类型相同,则一定不会出现多态;
如果编译时类型与运行时类型不相同,则不一定出现多态,前提是要出现子类对象的重写。

在这里插入图片描述

上转型对象:子类实例化的对象赋值给父类声明变量,则该对象称为上转型对象,这个过程称为对象上转型,对应于数据类型转换中的自动类型转换。
在这里插入图片描述

上转型对象不能调用子类新增的方法 和新增加的属性

在这里插入图片描述
其中weight和breathe方法都是子类中新的方法,所以上转型对象不能调用该方法
上转对象调用父类方法,如果该方法已被子类重写,则表现子类重写后的行为特征,否则表现父类的行为特征。

public class Mammal {
 public void move() {
  System.out.println("正在移动......");
 }//父类
 public void move() {
  System.out.println("用鱼鳍移动......");
  }//子类
  public  class Bat{
  public static void main(String[] args) {
  Mammal mammal=new  Whale();
  System.out .println(mammal.move);

此时出的将为"用鱼鳍移动",因为子类将该move方法重写,所以表现为子类重写后的行为特征;
使用上转型对象调用成员变量,无论该成员变量是否已经被子类覆盖,使用的都是父类中的成员变量:

public class Mammal {
 public void move() {
  System.out.println("正在移动......");
 }
 public String weight="1t";
}//父类的方法
System.out.println(new Whale().weight);
//  Mammal mammal = new Whale();
//  System.out.println(mammal.weight);

**所以问题:在上转型对象中如何实现调用子类新增的方法 和新增加的属性 **
此时我们需要采用对象下转型的方法

int price = (int)9.0;//类似于将double类型强制转换为int类型
Whale whale = (Whale)mammal;//其中whale为子类,mammal为父类

注意:下转型的前提是先出现上转型对象
Mammal mammal = new Mammal();//出现上转型对象
Whale whale = (Whale)mammal;//下转型对象

在多态的前提下,父类中被子类重写的方法没有必要有方法体

public abstract class Mammal {
 public abstract void move() ;
 public String weight="1t";
}

若一个类中有抽象方法则该类成为抽象类;
接口:若一个类中所有的方法均为抽象方法,那么这个抽象类称为接口。

Java 语言多态特性是通过两种方式实现的:继承和接口。 1. 继承实现多态性 继承是实现多态性的基本方式。子类可以继承父类的方法和属性,并且可以重写父类的方法。在程序运行,如果子类重写了父类的方法,那么调用方法将会执行子类方法。这就是动态绑定(动态多态性)的实现。例如: ``` class Animal { public void move() { System.out.println("Animal can move"); } } class Dog extends Animal { public void move() { System.out.println("Dog can run and walk"); } } public class Test { public static void main(String args[]) { Animal a = new Animal(); // Animal 对象 Animal b = new Dog(); // Dog 对象 a.move(); // 执行 Animal 类的方法 b.move(); // 执行 Dog 类的方法 } } ``` 上述代码,类 Animal 和类 Dog 都有一个名为 move() 的方法。在 main() 方法,我们声明了一个 Animal 对象 a 和一个 Dog 对象 b,并调用了它们的 move() 方法。由于 b 是 Dog 对象,因此它的 move() 方法将会覆盖 Animal 类的 move() 方法,输 "Dog can run and walk"。 2. 接口实现多态性 Java 还支持通过接口实现多态性。接口是一种抽象的数据类型,它只包含方法的声明,不包含实现。类可以实现一个或多个接口,在实现接口必须实现接口声明的所有方法。由于接口方法没有实现,因此在程序调用接口方法,实际执行的方法是实现该接口的类方法。例如: ``` interface Animal { public void move(); } class Dog implements Animal { public void move() { System.out.println("Dog can run and walk"); } } public class Test { public static void main(String args[]) { Animal a = new Dog(); // Dog 对象 a.move(); // 执行 Dog 类的方法 } } ``` 上述代码,接口 Animal 包含了一个名为 move() 的方法。类 Dog 实现了 Animal 接口,并重写了 move() 方法。在 main() 方法,我们声明了一个 Animal 对象 a,并将其赋值为一个 Dog 对象。由于 Dog 实现了 Animal 接口,并重写了 move() 方法,因此 a.move() 会执行 Dog 类的 move() 方法,输 "Dog can run and walk"。 综上所述,Java 语言多态特性是通过继承和接口实现的。在运行,程序会根据对象的实际类型调用相应的方法。这种动态绑定的特性使得程序更加灵活,具有更好的可扩展性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值