`
ayis
  • 浏览: 187183 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

父类同名变量的隐藏与方法的覆盖

    博客分类:
  • java
阅读更多

     最初是在java的头版看到 JAVA面试题解惑系列   对java中变量(属性)的覆盖 的一些讨论,那篇确实写的很好!但我有一个对别人说三道四的不好的坏毛病,觉得他的文章中“变量(属性)的覆盖”表述不对,其它也没什么,就发表了一篇对 JAVA面试题解惑系列(三)——变量(属性)的覆盖 的质疑 ,那是我javaeye上面的处女作,o(∩_∩)o...

     在以前的那篇文章中只是借鉴其它文章了对子类和父类定义同名成员作了一些总结,正如JAVA面试题解惑系列 的作者所说的那样。但那篇文章也有一定的参考价值,可以仔细的看一下。在这篇文章其实是想作为补充。下面不多说了,将由代码引出问题。

class Parent{
	
	int i=10;// 父类变量
	
	public void setI(int i){
		this.i=i;
	}
}

class Son extends Parent{
	int i=10;// 子类与父类同名的变量
	
	public static void main(String args[]){
		Son son=new Son();
		System.out.println("son.i="+son.i);
		son.setI(100);
		System.out.println("After setI(100) : son.i="+son.i);
		
		Parent parent=son;
		System.out.println("See son as Parent : son.i="+parent.i);
	}
	
}

 看运行的结果:

son.i=10
After setI(100) : son.i=10
See son as Parent : son.i=100

 下面来做解释:

    在这段代码中,子类定义了一个父类中同名的成员变量int i,在父类中有一个对 i 赋值的方法setI(),而在子类中没有定义这个方法。(请读者对照代码)。当子类调用继承而来的setI()方法对成员变量i进行改变,直接打印son.i(对照代码)时,成员变量i然而却没有改变,是不是很奇怪,o(∩_∩)o...哈哈。当但当把son当作Parent类型来使用,再打印它的成员变量i时,输出的结果就对了,是setI()改变之后的值。

    然而这是为什么呢?我到处弄了很久,觉得一种解释很合理:java中类是分层次的,当子类和父类的定义同名时,父类变量被隐藏,父类的实例方法被重写,静态方法属于类级别的方法,在子类和父类中互不相碍。虽然这句话也很简单,但理解起来还是不够明白。我想知道子类的对象创建时,它们在内存中是怎么变化的。

 

 

这java语言是java编写者们写的,规则是这么定的。

4
2
分享到:
评论
4 楼 lgh1992314 2017-10-25  
父类中的方法setI原型估计是

setI(Parent this, int i){...}
3 楼 cuitwind 2011-09-27  
最近面试到了。。都错了 当时没注意
2 楼 ayis 2008-09-24  
xwssole 写道

你如何用c++的对象模型来解释这个就非常容易理解吧。。。Derived Class虽然也能够调用setI方法,但是setI方法并不会为Derived Class生成一份代码,而是与Base Class共享一份代码。setI在调用的时候编译器会自动把this地址传递进去,这个this指针的类型就是Base*,它当然不能访问派生类的member variable了,所以它就修改了base class里面的i了。而base.i和derived.i这两个分别引用了base class和derived class的相应的i。

谢谢!说得非常好!比较好的做法是在Derived Class 中不要定义跟Base CLass相同的成员变量。
1 楼 xwssole 2008-09-10  
你如何用c++的对象模型来解释这个就非常容易理解吧。。。
Derived Class虽然也能够调用setI方法,但是setI方法并不会为Derived Class生成一份代码,而是与Base Class共享一份代码。
setI在调用的时候编译器会自动把this地址传递进去,这个this指针的类型就是Base*,它当然不能访问派生类的member variable了,所以它就修改了base class里面的i了。
而base.i和derived.i这两个分别引用了base class和derived class的相应的i。

相关推荐

    Java中的方法和变量在继承时的覆盖问题

    另外静态方法不能覆盖父类的实例方法,而静态变量却可以隐藏父类的一个同名实例变量,同样,实例方法不能覆盖父类的同名静态方法,而变量却可以隐藏父类的同名变量成员,不论父类的这个变量成员是类变量或者是实例...

    方法和变量在继承时的覆盖和隐藏问题

    而方法隐藏则意味着子类定义了一个与父类同名但签名不同的方法,或者定义了一个与父类同名的变量,这导致父类中的同名方法或变量不再直接可用。 具体到Java语言,方法覆盖(即方法重写)有一些限制: 1. 子类中的...

    论JAVA继承机制中父类与子类的关系

    - **成员变量的隐藏**:子类中定义的与父类同名的成员变量会隐藏父类中的同名成员变量。这意味着在子类内部,使用变量名时会优先引用子类的成员变量。 - **方法的覆盖**:子类中定义的与父类同名且具有相同参数列表...

    Java中方法的重写与成员变量的隐藏

    方法的重写是指在子类中重新定义父类中的方法,以便实现多态性,而成员变量的隐藏则是指在子类中定义与父类同名的成员变量,从而隐藏父类中的成员变量。 在 Java 中,方法的重写是通过在子类中重新定义父类中的方法...

    java类的继承详解说明

    如果子类的成员变量与父类同名,那么子类成员变量会覆盖掉父类的同名变量。这是因为变量名是变量的标识,系统是根据变量名去寻找对应变量的存储空间。 覆盖成员变量 如果父类的成员变量是 int 类型,子类同名变量...

    区分Java的方法覆盖与变量覆盖

    这与方法覆盖不同,方法覆盖在多态调用时会根据实际对象的类型执行相应的方法,而变量覆盖则不会改变父类引用所访问的变量。因此,变量覆盖并不完全等同于方法覆盖,它更像是一个"隐藏"行为,而不是真正的覆盖。 在...

    Java方法继承、方法重载、方法覆盖总结

    7. **覆盖与隐藏的区别**: 当子类中定义了一个与父类同名但参数列表不同的方法时,这实际上是一种“隐藏”,而非覆盖。 #### 四、super关键字 **super关键字**在Java中用于指代当前对象的直接父类对象。它主要用于...

    java 子类对象赋值给父类对象的使用

    3. **变量隐藏**:如果子类和父类有同名的实例变量,子类变量会“隐藏”父类变量。通过父类引用访问这些变量时,实际访问的是父类的变量,而非子类的。 4. **类型转换**:虽然父类引用可以指向子类对象,但反过来...

    Java中super变量.pdf

    当子类中存在与父类同名的成员变量时,子类的变量会隐藏父类的变量。这时,我们可以使用`super`关键字来访问父类中的隐藏变量。例如: ```java class Parent { int value = 10; } class Child extends ...

    java复习题.docx

    属性隐藏是指子类中定义了与父类同名的变量,此时子类的变量会隐藏父类的同名变量,但可以通过`super`关键字访问父类的同名变量。方法覆盖(重写)指的是子类中的方法与父类中的方法具有相同的名称、返回类型和参数...

    java练习册(012)--类的继承(1)分享.pdf

    5. 当子类声明了一个与父类同名的成员时,对于成员变量,子类的变量会隐藏父类的变量;对于方法,子类的方法会覆盖父类的方法。 三、创建子类 创建子类只需在类声明中包含`extends`关键字,指定父类。然而,通常在...

    JAVA复习习题(继承).pdf

    6. **方法覆盖与可见性**:子类可以覆盖父类的方法,但覆盖的方法必须具有相同的参数列表,且子类方法的访问权限不能低于父类方法。例如,如果父类有一个`public void myMethod(int a)`,子类不能定义为`private ...

    理学继承接口与泛型PPT课件.pptx

    - 当子类定义了与父类同名的变量,子类的变量会隐藏父类的同名变量,即使类型不同。 - 若要访问被隐藏的父类变量,需要使用`super.变量名`进行访问。 4. **方法的重写(覆盖)**: - 子类可以重写父类的方法,...

    继承与接口的含义以及其子类相关的含义

    方法覆盖发生在子类中,子类定义一个与父类同名且参数列表完全相同的方法,以改变或扩展父类的方法行为。 **this关键字** `this`关键字用于引用当前对象,常用于区分成员变量和局部变量,或者在构造器中调用其他...

    Java中子类.pdf

    覆盖则是指子类定义了一个与父类同名、同返回类型和相同参数列表的方法时,子类的方法将替代父类的方法。 隐藏和覆盖是面向对象多态性的体现。它们让子类有能力自定义继承的状态和行为,同时保持与父类的兼容性。...

    Java面向对象程序设计--继承与接口.pptx

    成员变量的隐藏发生在子类中声明了与父类同名的变量时,子类会优先使用自己定义的变量,而隐藏父类的变量。方法重写(Override)则发生在子类提供与父类相同名称和签名的方法,以便为特定的子类行为提供不同的实现。...

    完整版精品java课件 Java基础入门教程 Java程序设计 第5章 继承和接口(共47页).ppt

    当子类中定义了与父类同名的变量时,子类中的变量会隐藏父类的变量。同时,子类可以重写父类的方法,这通常是为了提供更具体的行为。例如,子类可以定义与父类方法签名完全相同的方法,从而覆盖父类的方法。 `super...

    java复习题.pdf

    6. **属性隐藏**:当子类中存在与父类同名的变量时,子类的变量会隐藏父类的同名变量。这意味着在子类中直接访问该变量时,实际上是在操作子类的变量。 7. **方法覆盖**(重写):如果子类的方法与父类的方法有相同...

Global site tag (gtag.js) - Google Analytics