java中的多态和继承---"编译看左边,运行看右边"(多态执行)
2015-05-03 17:05
316 查看
老毕的"编译看左边,运行看右边"(多态执行)
(对面向对象语言中理解多态、继承很有帮助~~~)
老毕在讲到多态执行问题时,结合下面的例子,给我们总结了一套口诀:“成员变量,静态方法看左边;非静态方法:编译看左边,运行看右边。”意思是:当父类变量引用子类对象时(Fu f = new Zi();),在这个引用变量 f 指向的变量/方法中,他对成员变量和静态方法的调用与父类是一致的,他调用非静态方法时,在编译时是与父类一致的(查看父类有没有该函数,没有就会发生编译错误,提示fu
中找不到要调用函数),运行时如果子类中发生了复写就与子类一致。(如果右边没有再看左边。若都没有才会报错)
例:
class Fu
{
int num = 5;
static void show()
{
System.out.println("fu show()");
}
void print()
{
System.out.println("fu print()");
}
}
class Zi extends Fu
{
int num = 8;
static void show()
{
System.out.println("zi show()");
}
void print()
{
System.out.println("zi print()");
}
}
class Demo
{
public static void main(String[] args)
{
Fu f = new Zi();
System.out.println(f.num);//与父类一致
f.show();//与父类一致
f.print();//编译时与父类一致,运行时与子类一致
Zi z = new Zi();
System.out.println(z.num);
z.show();
z.print();
}
}
输出结果:
5
fu show()
zi print()
8
zi show()
zi print()
个人分析:
Fu f = new Zi();----------首先了解变量F到底是什么,把这句子分2段:Fu f;这是声明一个变量f为Fu这个类,那么知道了f肯定是Fu类。然后我们f=newZi();中建立一个子类对象赋值给了f,结果是什么??
结果是,拥有了被Zi类函数覆盖后的Fu类对象----f------。
-------------------------------------------也就是说:
只有子类的函数覆盖了父类的函数这一个变化,但是f肯定是Fu这个类,也就是说f不可能变成其他比如Zi这个类等等(突然f拥有了Zi类特有函数,成员变量等都是不可能的)。所以f所代表的是函数被复写后(多态的意义)的一个Fu类,而Fu类原来有的成员变量(不是成员函数不可能被复写)没有任何变化----------------获得结论:A:成员变量:编译和运行都看Fu。
但是f的Fu类函数被复写了。--------------获得结论:B:非静态方法:编译看Fu,运行看Zi
对于静态方法:编译和运行都看Fu!!
其实很简单,首先我们要理解静态情况下发生了什么?
----------------当静态时,Fu类的所有函数跟随Fu类加载而加载了。也就是Fu类的函数(是先于对象建立之前就存在了,无法被后出现的Zi类对象所复写的,所以没发生复写,那么获得:C:静态方法:编译和运行都看Fu。
(对面向对象语言中理解多态、继承很有帮助~~~)
在多态中,成员变量的特点: 无论编译和运行,都参考左边(引用型变量所属的类) 在多态中,静态成员函数的特点:无论编译和运行,都参考做左边。
在多态中,非静态成员函数的特点:编译看左边,运行看右边。
老毕在讲到多态执行问题时,结合下面的例子,给我们总结了一套口诀:“成员变量,静态方法看左边;非静态方法:编译看左边,运行看右边。”意思是:当父类变量引用子类对象时(Fu f = new Zi();),在这个引用变量 f 指向的变量/方法中,他对成员变量和静态方法的调用与父类是一致的,他调用非静态方法时,在编译时是与父类一致的(查看父类有没有该函数,没有就会发生编译错误,提示fu
中找不到要调用函数),运行时如果子类中发生了复写就与子类一致。(如果右边没有再看左边。若都没有才会报错)
例:
class Fu
{
int num = 5;
static void show()
{
System.out.println("fu show()");
}
void print()
{
System.out.println("fu print()");
}
}
class Zi extends Fu
{
int num = 8;
static void show()
{
System.out.println("zi show()");
}
void print()
{
System.out.println("zi print()");
}
}
class Demo
{
public static void main(String[] args)
{
Fu f = new Zi();
System.out.println(f.num);//与父类一致
f.show();//与父类一致
f.print();//编译时与父类一致,运行时与子类一致
Zi z = new Zi();
System.out.println(z.num);
z.show();
z.print();
}
}
输出结果:
5
fu show()
zi print()
8
zi show()
zi print()
个人分析:
Fu f = new Zi();----------首先了解变量F到底是什么,把这句子分2段:Fu f;这是声明一个变量f为Fu这个类,那么知道了f肯定是Fu类。然后我们f=newZi();中建立一个子类对象赋值给了f,结果是什么??
结果是,拥有了被Zi类函数覆盖后的Fu类对象----f------。
-------------------------------------------也就是说:
只有子类的函数覆盖了父类的函数这一个变化,但是f肯定是Fu这个类,也就是说f不可能变成其他比如Zi这个类等等(突然f拥有了Zi类特有函数,成员变量等都是不可能的)。所以f所代表的是函数被复写后(多态的意义)的一个Fu类,而Fu类原来有的成员变量(不是成员函数不可能被复写)没有任何变化----------------获得结论:A:成员变量:编译和运行都看Fu。
但是f的Fu类函数被复写了。--------------获得结论:B:非静态方法:编译看Fu,运行看Zi
对于静态方法:编译和运行都看Fu!!
其实很简单,首先我们要理解静态情况下发生了什么?
----------------当静态时,Fu类的所有函数跟随Fu类加载而加载了。也就是Fu类的函数(是先于对象建立之前就存在了,无法被后出现的Zi类对象所复写的,所以没发生复写,那么获得:C:静态方法:编译和运行都看Fu。
相关文章推荐
- java中的多态和继承---"编译看左边,运行看右边"(多态执行)
- 多态——"编译看左边,运行看右边"
- JAVA继承:编译与运行的关系(编译看左边,运行看右边)
- Eclipse下好使,但是cmd下执行java运行class文件提示Exception in thread "main" java.lang.NoClassDefFoundError问题
- 关于java文件编译后,同一个文件出现"$"的class
- 为什么执行JAVA程序时,会出现Exception in thread"main" java.lang.NoClassDefFoundError的错?...
- 可执行程序无法在Linux上运行,显示line 1: syntax error: word unexpected (expecting ")
- 可执行程序无法在Linux上运行,显示line 1: syntax error: word unexpected (expecting ")
- OO中的继承分析,主要分析在编译和运行过程中子类父类的方法、字段和实例化时候在内存中分配和执行的先后,以及两个原则
- 编写的exe在别的机器上运行的时候总是报错 "找不到MSVCR100.dll 请重新安装",编译的机器上又不会报,这是怎么回事啊?是不是因为编译的机器上有特殊的配置?
- 第一个slice2java的项目运行异常:Cannot run program "slice2java": CreateProcess error=2;解决方案诧异
- 在命令提示符下编译、运行java 以及使用jar命令制作可执行的jar包
- 【java & c#】通过控制台编译和运行程序//不依赖IDE
- 可执行程序无法在Linux上运行,显示line 1: syntax error: word unexpected (expecting ")" )
- 10 Java中的多态是运行时行为or编译时行为
- java编译中说"类A是公共的,应在名为A.java的文件中声明"是怎能么回事?
- Eclipse下好使,但是cmd下执行java运行class文件提示Exception in thread "main" java.lang.NoClassDefFoundError问题
- Eclipse下好使,但是cmd下执行java运行class文件提示Exception in thread "main" java.lang.NoClassDefFoundError问题
- 使用java 命令运行出现"仅当显式请求注释处理时才接受类名称"的简单处理
- 编译eclair碰到java version "1.5.0_18"问题的解决