【Java学习笔记】如何理解java中的“编译看左边,运行看右边”

java中的继承是面向对象程序设计的一大特征,子类继承了父类的所有方法和成员变量,如果不对方法进行重写或对成员变量进行重新赋值,那么子类可以直接调用父类中的方法或变量。同时,在实例化父类的时候,可以使用子类的构造器。

但是,在这种情况下,调用这个父类对象中的方法和变量时,到底是使用父类的呢还是子类的呢?我们首先来创建两个类:

public class Cat extends Animal{
        static String name = "cat";	
        int num = 2;
	public static void sleep() {
		System.out.println("cat sleep");
	}
        public void run() {
		System.out.println("cat run");
	}
}

可以看到,Animal类中声明了静态成员变量name、成员变量num、方法run()和静态方法sleep(),同时子类Cat中也重写了这两个两个方法。下面,我们用Cat的构造方法来实例化一个Animal,再实例化一个Cat对象。

public static void main(String args[]) {
		
		Cat cat = new Cat();
		
		Animal animal = new Cat();
		
		System.out.println(cat.num);
		System.out.println(animal.num);
		System.out.println(cat.name);
		System.out.println(animal.name);
		cat.run();
		animal.run();
		cat.sleep();
		animal.sleep();
	}

运行后可以看到:

2

1

cat

animal

cat run

cat run

cat sleep

animal sleep


可以看到,在输出两个对象中的各个变量时,Animal对象并没有因为构造函数使用了其子类而输出子类中的成员变量值,但是,在调用成员变量的时候就不一样了,在调用run()方法时,Animal输出和Cat一样的结果,而在调用静态方法sleep()的时候,两个对象又分别输出了其各自的结果。


可以这样总结,在调用成员变量以及静态方法时,“编译看左边,运行看左边”,即程序编译时创建了一个Animal类型的对象,并且使用new Cat()对于这个Animal对象赋值,但最终得到的还是一个Animal类的对象,只需要看“=”左边的Animal animal即可。


但是要调用非静态方法时,由于Animal类的对象是用Cat()来实例化的,这个非静态方法在运行时会被重写,从而输出子类中方法重写后的结果。这就是“编译看左边,运行看右边”。


猜你喜欢

转载自blog.csdn.net/u012198209/article/details/80064049