关于向上转型和方法多态

一直以来我都不太明白为什么大家的代码中创建一个ArrayList对象都是用

List temp = new ArrayList();

所以今天来整理一下向上转型的。。实际效果!
首先看一段简单的代码:


public class test extends A {
  public int a = 2;

  public int getNum() {
  return a;
  }

  public int getNew() {
    return 3;
  }

public static void main(String[] args) {
    A temp = new test();
    System.out.println(temp.a);
    System.out.println(temp.getNum());
    //System.out.println(temp.getNew());
  }
}

class A{
  public int a = 1;

  public int getNum() {
  return a;
  }
}

输出结果为

1
2

结果很明显,调用相同名字的属性(变量)结果取决于引用类型,即A,当然由于封装的关系一般不会用到这一点。
而方法则要看引用的实际类型,即test。而如果把main中第四行的引用去掉,则会报错。我的理解是引用类型为父类时,只能调用父类中声明的方法,不过实际调用时会从引用变量的实际类型入手开始检查方法名,子类没有重写则检查父类直到找到方法为止,这就是Java特性中多态的方法多态

那这有什么用呢?从上面的效果可以看出,因为正常情况下我们会对类进行封装,所以对属性的引用的特点我们无需管。所以使用场景多是运用方法多态。

abstract class A{
  static int getNum(A temp) {
    return temp.createNum();
  }

  protected abstract int createNum(){}
}

对于方法getNum(A temp),参数可以接收所有A的子类型去调用子类型中各自实现不同的的createNum()。

对上面的情况使用这一特性可以减少代码量,还有另外的使用场景是Java设计模式-装饰器模式和Java设计模式-策略模式,唔。。应该还有很多使用场景,后续看到会补充进来。

还有另外一种情况,当我们定义了

List temp = new ArrayList();
当我们不需要这个ArrayList而需要temp指向一个LinkedList时,可以直接
temp = new LinkedList
();
避免了再定义一个变量,节约了内存和分配空间的时间。

在上面的使用场景中向上转型增强了适应性,套路也大同小异;当然对于需要调用一些子类中特有的方法的场景,我们可以不使用向上转型或进行向下转型(强制类型转换)。

你可能感兴趣的:(关于向上转型和方法多态)