表面类型:对象声明时的类型;
实际类型:对象产生时的类型;
那么在继承关系中,方法时如何执行的呢?例子以下:
例子1
COne[表面类型] one = new CTwo[实际类型]();
class COne {
public void f() {
System.out.println("COne.f");
}
}
class CTwo extends COne{
public void f() {//2.one.f()执行了这个方法
System.out.println("CTwo.f");
}
}
class CThree {
public void g(COne one) {//1.three.g(one)执行了这个方法
System.out.println("g(Cone)");
one.f(); //当用对象名.去使用方法的时候,调用的是实际类型的的方法
}
public void g(CTwo two) {
System.out.println("g(Ctwo)");
two.f();
}
}
public class Main {
public static void main(String[] args) {
COne one = new CTwo(); //表面类型是COne,实际类型是CTwo
CThree three = new CThree();
three.g(one);//当传参进来使用时,使用的是表面类型
}
}
A.
g(Cone)
CTwo.f
B.
g(Cone)
COne.f
C.
g(Ctwo)
CTwo.f
D.
g(Ctwo)
COne.f
答案是A
因此我们可以知道:
- 方法传参进去时看的是表面类型
- 对象名.方法调用时看的是实际类型
例子2
Base[表面类型]base=new Sub[实际类型]();
public class StaticTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Base base=new Sub();
base.doSomeThing1();
base.doSomeThing();
}
}
class Base{
public static void doSomeThing()//静态方法
{
System.out.println("Base method---doSomeThing");
}
public void doSomeThing1()
{
System.out.println("Base method---doSomeThing1");
}
}
class Sub extends Base{
public static void doSomeThing()//静态方法
{
System.out.print("Sub method---doSomeThing");
}
@Override
public void doSomeThing1()
{
System.out.print("Sub method---doSomeThing1");
}
}
咱们发现静态方法居然执行的不是子类中的方法,这是因为:
-
非静态方法是按照实际类型执行的;
-
静态方法是按照表面类型来执行的;
可是,经过子类构建与父类彻底相同的静态函数,这中行为叫作“隐藏”,其目的就是抛弃父类的静态方法,重显子类方法。
拓展:
静态和非静态的区别(static):
(1)首先静态方法中只能有静态成员变量,不能有非静态的普通成员变量。
非静态方法中,没有限制。
(2)其次,在访问方式上。 静态方法只能访问静态方法,不能访问非静态的普通方法。
非静态方法则没有限制。