Java入门——多态

Java引用变量有两个类型分别是

编译时类型:声明的类型

运行时类型:实际赋值的类型

如果这两个类型不一样就会出现多态

举例现有类A

class A{
	public int field = 5;
	
	public void fun(){
		System.out.println("A类的方法1");
	}
	
	public void funA(){
		System.out.println("A类的方法A");
	}
}

B类继承A类

class B extends A{
	public String field = "B类的字符串field";
	
	public void fun(){
		System.out.println("B类的方法1");
	}
	
	public void funB(){
		System.out.println("B类的方法B");
	}
}

两个类都有实例变量field,一个为整型,一个为字符串
两个类都有不同的普通实例方法分别是funA()和funB()
A类中的fun()被B类重写了

一般情况下我们会这么写

A a = new A();
System.out.println(a.field);
a.fun();
a.funA();

输出为

5
A类的方法1
A类的方法A

或者我们会这么写

B b = new B();
System.out.println(b.field);
b.fun();
b.funB();

输出为

B类的字符串field
B类的方法1
B类的方法B

以上两种情况中,我们声明了一个类A(或B)的的引用变量a(或b),并且new了一个类A(或B)的实例
说明编译类型运行类型一致,不会出现什么特殊的情况

但是如果我们写

A c = new B();

情况就会变得特殊一些,我们声明了一个类A(编译类型)的引用变量c,但其实际被赋值为类B(运行类型)的一个实例引用
这时就产生了多态

System.out.println(c.field);

我们输出c的field变量,结果为5,说明访问的是父类A的实例变量

c.fun();

我们调用方法fun()发现输出为“B类的方法1”,说明此时访问的是子类B的实例方法

这就是多态

总结:多态的情况下,调用实例方法时,总是表现出子类方法(运行时类型)的行为特征,而实例变量不存在多态性,系统总是试图访问其定义类型(编译时类型)的实例变量

一个特别需要注意的是,以下的代码将引发编译错误

c.funB();

这是因为引用变量c的编译类型为类A,而类A中不含有方法funB(),即使c确实含有这个方法

posted @ 2019-02-13 12:38  Velscode  阅读(87)  评论(0编辑  收藏