多态中访问变量、实例方法、静态方法的区别

先上结论

在多态中,变量和静态方法都是与类相挂钩的,和具体的对象是哪个无关。而实例方法的访问可以通过一条口诀来记忆:编译看左边,运行看右边

结论验证

1. 访问变量和静态方法

之所以将它们俩归在一起总结,是因为结论很类似,但实际上,静态内容和实例内容差别是很大的。
比如 Parent p = new Child(); 如果是通过引用p去方法静态方法或者变量,那么访问的一定是父类中的内容,无论子类中是否存在与父类同名的静态方法或变量。

public class Parent
{
	// 成员变量
	public String publicString = "父类public修饰的成员变量";
	// 静态变量
	public static String staticString = "父类static修饰的静态变量";
	
	// 静态方法
	public static void method2()
	{
		System.out.println("父类public static修饰的成员方法");
	}
	
	public static void main(String[] args)
    {
        Parent p = new Child();
        System.out.println(p.publicString );
        System.out.println(p.staticString);
        p.method2();
    }
}
class Child extends Parent 
{
	//与父类同名的成员变量
    public String publicString = "子类public修饰的成员变量";
    //与父类同名的静态变量
    public static String staticString = "子类static修饰的成员变量";

	// 与父类重名的静态方法
    public static void method2()
    {
        System.out.println("子类public static修饰的成员方法");
    }
}

输出结果
父类public修饰的成员变量
父类static修饰的静态变量
父类public static修饰的成员方法

2.访问实例方法

实例方法才是多态的表现,静态方法和变量在多态中都是无效的。在 Parent p = new Child();中,使用引用p去调用实例方法,需要Parent类中有这个实例方法,才能编译通过,这称为静态绑定。但是在运行的时候,需要去在Child中寻找对应的方法,称为动态绑定。

public class Parent
{
	// 父类中的成员方法
	public void method1()
	{
		System.out.println("父类public修饰的成员方法");
	}
	
	public static void main(String[] args)
    {
        Parent p = new Child();
        p.method1();
    }
}
class Child extends Parent 
{
	// 与父类重名的成员方法
    public void method1()
    {
        System.out.println("子类public修饰的成员方法");
    }
}

运行结果:
子类public修饰的成员方法

但是,好像在子类中不重写父类的方法,好像一样可以调用方法。

public class Parent
{
	// 父类中的成员方法
	public void method1()
	{
		System.out.println("父类public修饰的成员方法");
	}
	
	public static void main(String[] args)
    {
        Parent p = new Child();
        p.method1();
    }
}
class Child extends Parent 
{
	// 子类中没有重写父类的method1方法
}

运行结果
父类public修饰的成员方法

虽然看起来好像是调用了父类中的方法,但实际上是因为子类继承了父类中的这个方法,运行的时候,还是去子类中寻找的。

猜你喜欢

转载自blog.csdn.net/ql_7256/article/details/107349936