关于继承的方法和变量
2007-01-06 19:44
369 查看
有些东西真是一天不想就忘了,前段时间看了关于继承的方法和变量的调用,是调用的子类方法,还是调用父类的方法,感觉搞明白了,今天突然想起来,竟然发现给忘记了,呵呵,所以把它记下来,以便再忘了的时候,可以找出来看看。
class FatClass{
int var = 1;
public void methodA(){
System.out.println("A");
}
public static void methodB(){
System.out.println("SA");
}
}
class SubClass extends FatClass{
int var = 2;
public void methodA(){
System.out.println("B");
}
public static void methodB(){
System.out.println("SB");
}
}
public class Test{
public static void main(String[] args){
FatClass test = new SubClass();
System.out.println(test.var);
test.methodA();
test.methodB();
}
}
其实主要就是关于上面程序的思考。写了一个父类一个子类。父类中写了两个方法和一个变量,子类覆盖了父类的方法和变量。当在程序中声明一个父类的引用,创建一个子类的实例的时候,调用的是父类的方法还是子类的方法,调用的是父类的变量,还是子类的变量的问题。
这里牵掣到了隐藏的概念,也就是说如果定义的是父类引用,实例的也是父类的引用,或者定义的是子类的引用,实现的也是子类的引用,那么无可厚非,定义的是谁,调用的就是谁的方法和变量,但是如果定义的是父类的引用,实现的却是子类,那么在遇到实例方法的时候,实例的是哪个类,就调用那个类的方法,比如这里,test调用methodA的时候,就打印出B字母。父类实例方法被隐藏了。但是调用静态方法methodB的时候,无论实例的是哪个类,都会调用父类的方法,也就是说这里会打印出SA,我是这样理解的,因为静态方法独立于实例存在,也就是说当我们在定义引用的时候FatClass test的时候,静态方法static methodB就已经存在了,这时候就算子类覆盖了方法,但是虚拟机在看到是父类引用类型的时候,就直接找到了那个已经存在了的父类的静态方法,就没有去实例子类的静态方法。
所以以上程序运行结果是
1
B
SA
就可以理解了。
下面是一则关于这个问题的FAQ:
Q. Base b = new SubBase(); How the compiler/Runtime to resolve the addresses of methods calls, Fields?
// TestBinding.java
class Base {
String s = "string in Base";
void amethod(){
System.out.println("amethod() call in Base");
}
}
class SubBase extends Base{
String s = "string in SubBase";
void amethod(){
System.out.println("amethod() call in SubBase");
}
}
public class TestBinding {
public static void main(String[] args) {
Base b = new SubBase();
// static binding on instance fields
System.out.println(b.s); //string in Base
// dynamic binding on instance methods
b.amethod(); //amethod() call in SubBase
}
}
A:
The above example plus comments actually told everything you need to know.
When a variable of an object is accessed using a reference, it is the type of the reference, not the class of the current object denoted by the reference, that determines which variable will actually be accessed.
Static Binding -- Bind at compile time : The addressing of the variable is determined at compile time.
When a method is invoked on an object using a reference, it is the class of the current object denoted by the reference, not the type of the reference, that determines which method implementation will be executed.
Dynamic Binding -- Bind at run time: The addressing of the method is determined at run time.
这里就说的很清除了,变量是静态绑定的,方法是动态绑定的。
下面是相关的一个FAQ:
Q. If I remove the amethod() from the Base class defined in the above question, I got a compile error: ""method amethod() not found class Base". Why?
A: Incredible great question!!
It will make you understand dynamic binding or polymorphism much much better.
If you remove amethod() from Base class, you actually take amethod() out of the polymorphism between Base and SubBase class. Compiler only know b is refer to a Base class, which does not have the method amethod(), compile time error!!!
Remember SubBase ISA Base. Compiler does not care which child/grandchild/grandgrandchild down the hierarchy b is actually referring to, and which amethod() it should call. However, they all have an amethod()
(polymorphism). It is a runtime decision. Dynamic Binding.
Dynamic binding, or binding at runtime only for those methods defined in Base class , either inherited or overrided by the subclass. The override can be already happened now or will happen in the future, the compiler does not care.
class FatClass{
int var = 1;
public void methodA(){
System.out.println("A");
}
public static void methodB(){
System.out.println("SA");
}
}
class SubClass extends FatClass{
int var = 2;
public void methodA(){
System.out.println("B");
}
public static void methodB(){
System.out.println("SB");
}
}
public class Test{
public static void main(String[] args){
FatClass test = new SubClass();
System.out.println(test.var);
test.methodA();
test.methodB();
}
}
其实主要就是关于上面程序的思考。写了一个父类一个子类。父类中写了两个方法和一个变量,子类覆盖了父类的方法和变量。当在程序中声明一个父类的引用,创建一个子类的实例的时候,调用的是父类的方法还是子类的方法,调用的是父类的变量,还是子类的变量的问题。
这里牵掣到了隐藏的概念,也就是说如果定义的是父类引用,实例的也是父类的引用,或者定义的是子类的引用,实现的也是子类的引用,那么无可厚非,定义的是谁,调用的就是谁的方法和变量,但是如果定义的是父类的引用,实现的却是子类,那么在遇到实例方法的时候,实例的是哪个类,就调用那个类的方法,比如这里,test调用methodA的时候,就打印出B字母。父类实例方法被隐藏了。但是调用静态方法methodB的时候,无论实例的是哪个类,都会调用父类的方法,也就是说这里会打印出SA,我是这样理解的,因为静态方法独立于实例存在,也就是说当我们在定义引用的时候FatClass test的时候,静态方法static methodB就已经存在了,这时候就算子类覆盖了方法,但是虚拟机在看到是父类引用类型的时候,就直接找到了那个已经存在了的父类的静态方法,就没有去实例子类的静态方法。
所以以上程序运行结果是
1
B
SA
就可以理解了。
下面是一则关于这个问题的FAQ:
Q. Base b = new SubBase(); How the compiler/Runtime to resolve the addresses of methods calls, Fields?
// TestBinding.java
class Base {
String s = "string in Base";
void amethod(){
System.out.println("amethod() call in Base");
}
}
class SubBase extends Base{
String s = "string in SubBase";
void amethod(){
System.out.println("amethod() call in SubBase");
}
}
public class TestBinding {
public static void main(String[] args) {
Base b = new SubBase();
// static binding on instance fields
System.out.println(b.s); //string in Base
// dynamic binding on instance methods
b.amethod(); //amethod() call in SubBase
}
}
A:
The above example plus comments actually told everything you need to know.
When a variable of an object is accessed using a reference, it is the type of the reference, not the class of the current object denoted by the reference, that determines which variable will actually be accessed.
Static Binding -- Bind at compile time : The addressing of the variable is determined at compile time.
When a method is invoked on an object using a reference, it is the class of the current object denoted by the reference, not the type of the reference, that determines which method implementation will be executed.
Dynamic Binding -- Bind at run time: The addressing of the method is determined at run time.
这里就说的很清除了,变量是静态绑定的,方法是动态绑定的。
下面是相关的一个FAQ:
Q. If I remove the amethod() from the Base class defined in the above question, I got a compile error: ""method amethod() not found class Base". Why?
A: Incredible great question!!
It will make you understand dynamic binding or polymorphism much much better.
If you remove amethod() from Base class, you actually take amethod() out of the polymorphism between Base and SubBase class. Compiler only know b is refer to a Base class, which does not have the method amethod(), compile time error!!!
Remember SubBase ISA Base. Compiler does not care which child/grandchild/grandgrandchild down the hierarchy b is actually referring to, and which amethod() it should call. However, they all have an amethod()
(polymorphism). It is a runtime decision. Dynamic Binding.
Dynamic binding, or binding at runtime only for those methods defined in Base class , either inherited or overrided by the subclass. The override can be already happened now or will happen in the future, the compiler does not care.
相关文章推荐
- 关于继承时子类重写父类方法和覆盖父类变量的若干问题 (待进一步研究)
- 关于JAVA继承类的静态变量、成员变量、父子类构造方法调用顺序的探讨
- 黑马程序员1——关于Java的继承过程中成员变量与方法的隐藏与覆盖
- 关于JAVA继承类的静态变量、成员变量、父子类构造方法调用顺序的研究
- 关于JAVA继承类的静态变量、成员变量、父子类构造方法调用顺序的探讨 .
- Lesson_for_java_day09--继承、实例化、构造方法、覆盖、重载、this关键字、super关键字、全局变量和局部变量
- ES6下关于对象继承的新方法
- 继承基础--成员变量和方法的动态绑定-测试
- 关于java的JDK环境变量设置方法及相关问题解决方案
- 继承成员变量和方法的区别
- java基础(八)Math/代码块/继承成员方法指南的关系/继承中成员变量之间的关系/方法的重写/继承中构造方法之间的关系/this和super的区别
- Java 继承 父类变量, 方法 与子类的关系:
- 继承成员变量和继承方法的区别
- 继承中关于基类私有方法的问题
- JAVA中方法和变量在继承中的覆盖和隐藏
- 关于在onCreate()方法中定义变量和在方法体外定义变量的区别
- wap流量统计代码:关于获取服务器环境变量的方法
- 关于java中final方法,类,成员变量的讨论
- 关于static方法和变量,举例说明
- 关于方法的继承和覆写