多态性
多态性有两种实现模式
1、方法的多态性
- 方法的重载:同一个方法名称可以根据传入的参数的类型和个数的不同实现不同的功能执行
- 方法的覆写:同一个方法可能根据使用子类的不同有不同的实现
2、对象的多态性
- 父子实例之间的转换处理,有两种模式
- 对象向上转型 父类 父类实例 = 子类实例 Person per = new Student();
- 通过子类对象(小范围)实例化父类对象(大范围),这种属于 自动转换
- 对象向下转型 子类 子类实例 = (子类)父类实例 Student stu = (Student) per;
- 通过父类对象(大范围)实例化子类对象(小范围),这种属于 强制转换
- 对象向上转型 父类 父类实例 = 子类实例 Person per = new Student();
向上转型实例:
class Person{ // 创建一个人的类
public String getInfo(){
return "Person 类输出";
}
}
class Student extends Person{ // 学生类继承人类
public String getInfo(){ // 覆写Person类方法
return "Student 类输出";
}
}
public class JavaDemo {
public static void main(String[] args) {
// 使用 new 开辟的一个 Student 类,然而赋值给Person类,向上转型;
Person per = new Student();
/*
这里调用的是Student类的getInfo()方法
因为我们通过子类Student去实例化Person
父类Person中的getInfo()方法已经被覆写了,从而调用的是Student的getInfo()
*/
System.out.println(per.getInfo());
}
}
// 运行结果
Student 类输出
向上转型作用分析:
向上转型优缺点分析:
优点: 向上转型描述的是一个子类共同具有的概念。
例如:汽车类(内含run()方法、speed()方法) 下有 宝马(内含run()方法、speed()方法)、奔驰(内含run()方法、speed()方法、price()方法)子类。我们通过向上转型,就可以通过一个show()函数描述他们共同具有的方法(run()、speed()),否则就要重载两个方法。这样代码具有简洁性。
缺点: 向上转型将会损失子类中的其他方法,转型之后只能使用父类中的方法以及被子类覆写的方法。为了弥补这一缺陷,因此可以使用向下转型。
向下转型:
instanceof 关键字
向下转型是存安全隐患的操作,所以为了保证向下转型的正确性,往往需要在转型之前判断某个实例是否为某个类的对象, 这就需要instanceof 语法实现。
对象名 instanceof 类名 返回布尔型
class Person{ // 创建一个人的类
public String getInfo(){
return "Person 类输出";
}
}
class Student extends Person{ // 学生类继承人类
public String getInfo(){ // 覆写Person类方法
return "Student 类输出";
}
}
class Teacher extends Person{
public String getInfo(){ // 覆写Person类方法
return "Teacher 类输出";
}
}
public class JavaDemo {
public static void main(String[] args) {
// 使用 new 开辟的一个 Student 类,然而赋值给Person类,向上转型;
Person per = new Student();
System.out.println(per instanceof Student); // 返回true
System.out.println(per instanceof Teacher); // 返回false
}
}
// 运行结果
true
fasle
在Java中,向下转型则是为了,通过父类强制转换为子类,从而来调用子类独有的方法
向下转型实例
class Person{ // 创建一个人的类
public String getInfo(){
return "Person 类输出";
}
}
class Student extends Person{ // 学生类继承人类
public String getInfo(){ // 覆写Person类方法
return "Student 类输出";
}
public String stduy(){
return "学生学习";
}
}
class Teacher extends Person{
public String getInfo(){ // 覆写Person类方法
return "Teacher 类输出";
}
public String teach(){
return "老师教书";
}
}
public class JavaDemo {
public static void func(Person per){ // 这里隐含了一个向上转型的过程
System.out.println(per.getInfo());
if(per instanceof Student){
Student std = (Student) per; // 向下转型为学生类
System.out.println(std.stduy()); // 调用学生类独有的方法
}else if(per instanceof Teacher){
Teacher tea = (Teacher) per; // 向下转型为教师类
System.out.println(tea.teach()); // 调用教师类独有的方法
}
}
public static void main(String[] args) {
func(new Person());
func(new Student()); // 这里的实际参数为 Studnet 类,形参接收为Person类,隐含一个向上转型
func(new Teacher());
}
}
// 运行结果
Person 类输出
Student 类输出
学生学习
Teacher 类输出
老师教书
Process finished with exit code 0
注意 : 在发生向下转型之前一定要有向上转型,两个没有任何关系的实例如果发生强制转换,会出现“ClassCastException” 异常,向下转型不是安全的,目的是调用子类功能。