目录
前言
本次给大家带来Java面向对象三大特征中的最后大特征——多态。前面我们学习到了封装和继承,本次的多态则是在前两个基础上延伸而来。多态可以消除类型之间的耦合关系,从而使程序更加的具有拓展性和维护性。下面给大家带来更详细的讲解!
多态概述
多态是指不同类的对象在调用同一个方法时所呈现出的多种不同的行为。也就是说同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,一个接口,多种实现。这就是多态性。简单的说:就是用基类的引用指向子类的对象。
方法的多态
当然方法也是存在多态性的,前面我们学习过的方法重写以及方法重载都可以体现出方法的多态。示例:
public class A {
public int sum(int a,int b){
return a+b;
}
public int sum(int a,int b,int c){
return a+b+c;
}
public void method(){
System.out.println("A类中的方法");
}
}
public class B extends A {
/*重写A类中的方法*/
@Override
public void method() {
System.out.println("B类中的方法");
}
}
测试类:
public class Test {
public static void main(String[] args) {
A a = new A();
// 方法重载体现了多态
System.out.println(a.sum(1, 2));
System.out.println(a.sum(1, 2,3));
B b = new B();
// 方法重写体现了多态
a.method(); //A类中的方法
b.method(); //B类中的方法
}
}
方法形参为对象引用时,调用方法可以将该类实例或子类的实例当做实参这也体现了多态。
对象的多态
对象的多态是重难点,也是本章要讲的核心。一个对象的编译类型和运行类型可以不一样。编译类型对象创建时就确定的,不可发生改变,运行类型可以发生改变。创建对象时,等号左边是编译类型,相反右边为运行类型。
向上转型
简而言之向上转型就是父类的引用指向了子类对象。
父类类型 对象名 = new 子类类型();
public class Animal {
String name;
public void run(){
System.out.println("动物跑...");
}
public void cry(){
System.out.println("动物叫...");
}
}
class Cat extends Animal{
String name="猫";
@Override
public void run() {
System.out.println("猫在跑...");
}
//子类特有的方法
public void catch(){
System.out.println("猫抓鱼...");
}
}
测试类:
public class AnimalTest {
public static void main(String[] args) {
//向上转型 父类的引用 指向 子类的对象
Animal animal = new Cat();
animal.run();
animal.cry();
//animal.catch(); //不能调用子类特有方法,该对象编译类型该是animal类,该类没有此方法
}
}
控制台打印结果:
猫在跑...
动物叫...
根据控制台结果可以得出以下结论:
- 编译类型决定了能够被调用的方法,编译类型类中没有的方法不可以被调用,例如子类中特有的方法不能够被调用。
- 调用的具体实现从运行类型类中方法中开始查找,如果没有则依次向父类查找。
向下转型
在向上转型中可以看到,new Cat()创建的对象本质就是Cat类型,当我们想要调用Cat类中特有的方法(父类中所没有的方法)时,该怎么解决? 可以通过向下转型,也就是强制类型转换,将父类类型的对象转换成子类类型。将animal对象转换成Cat类型。
子类类型 对象名 = (子类类型) 父类对象;
注意:这样做的前提是父类引用已经指向了子类对象,并且必须转换成本质类对象,也就是父类引用最开始所指向的对象。
Animal animal = new Cat();
Cat cat= (Cat) animal; //向下转型
cat.Catch();
System.out.println(cat.name);
这样做就可以调用子类中特有的方法了。
instanceof关键字
当我们使用向下转型时,如果我们不确定该对象的本质是否为需要转换的对象,可以使用instanceof关键字。它可以判断一个对象是否为某个类的实例或者子类实例。
代码实例如下:
Animal animal = new Cat();
//判断animal对象是否为Cat的实例,如果是则向下转型。
Cat cat = animal instanceof Cat ? ((Cat) animal) : null;