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

对 JAVA面试题解惑系列(三)——变量(属性)的覆盖 的质疑

    博客分类:
  • java
阅读更多

上次看了这篇文章,原文地址:

JAVA面试题解惑系列(三)——变量(属性)的覆盖


这篇文章给出了很好的解疑方法,我也是跟着他来。。。下面我的文章将讲到:java中成员变量和方法的覆盖问题


对那篇文章中的提到的变量覆盖,我不同意。因此,在这里首先提出我的观点:


当子类继承父类的成员变量或方法同名时,


同名静态方法被隐藏,同名实例方法被覆盖;可见同名成员变量均被隐藏;同名不可见方法和成员变量不存在覆盖或隐藏问题,因为不可见。


首先来解释下隐藏覆盖的区别:隐藏是指在某种情况下仍可恢复,而覆盖则是指永远不可恢复。下面再来分别解释这三句话:


1、同名静态方法被隐藏,同名实例方法被覆盖


我们先看这段程序代码:

class ParentMethord{

// 静态方法
static void getClassName(){
System.out.println("static: "+ParentMethord.class.getName());
}

// 实例方法
void getName(){
System.out.println(ParentMethord.class.getName());
}
}

public class SubMethord extends ParentMethord{

// 重写父类静态方法
static void getClassName(){
System.out.println("static: "+SubMethord.class.getName());
}

// 重写父类实例方法
void getName(){
System.out.println(SubMethord.class.getName());
}


public static void main(String args[]){

ParentMethord parent= new SubMethord();
SubMethord sub=(SubMethord)parent;

parent.getClassName(); // 静态方法调用的仍然是父类的方法
parent.getName(); // 实例方法调用的是子类的方法

System.out.println();


sub.getClassName(); // 子类中调用的当然是子类的方法
sub.getName();
}
}

 

运行的结果为:

static: ParentMethord
SubMethord

 

static: SubMethord
SubMethord

 

从这里可以看出当把一个子类对象自动转型为父类对象(ParentMethord parent= new SubMethord(); )时,同名静态的方法只是被隐藏起来了,转型为父类后仍然可以调用;而同名实例方法是被覆盖,转型后调用的也是子类的方法,即方法的重写。

 

2、同名成员变量均被隐藏

 

下面来讨论这一点。这里所说的成员变量包括静态成员变量和实例成员变量,(包括final型的),当然均是指父类中对子类可见的变量。

 

看代码:

 

 class Parent{
 static String staticStr="父类静态变量";
 
 String str="父类实例变量";
}

public class SubVariable extends Parent{
 
 static String staticStr="子类静态变量";
 
 String str="子类实例变量";
 
 public static void main(String args[]){
  
  Parent parent= new SubVariable();
  SubVariable sub = (SubVariable)parent;

  
  System.out.println(parent.staticStr);
  System.out.println(parent.str);
  
  System.out.println();
  
  System.out.println(sub.staticStr);
  System.out.println(sub.str);
 }
}

 

运行结果为:

 

父类静态变量
父类实例变量

 

子类静态变量
子类实例变量

由此可见成员变量均只是被隐藏,当自动转型为父类时,仍然可见。final型的也一样,这里就不再讨论。

 

插入: 在这里还想扯到一个话题,以前总听胡总告诫:不要直接用来访问对象成员变量,而用方法来访问。从这里有所体会。因为子类对象和父类对象成员变量如果出现重名 ,当把一个子类对象当作父类使用时,访问的是父类对象的那个成员变量,就会出现数据的不一致;而用方法来方法问成员变量,由于方法被重写就不会出现这个问题。可以看如下代码:

 

class Parent{
 static String staticStr="父类静态变量";
 
 String str="父类实例变量";

 public static String getStaticStr() {
  return staticStr;
 }

 public String getStr() {
  return str;
 }

}

public class SubVariable extends Parent{
 
 static String staticStr="子类静态变量";
 
 String str="子类实例变量";
 
 public static String getStaticStr() {
  return staticStr;
 }

 public String getStr() {
  return str;
 }
 
 public static void main(String args[]){
  
  Parent parent= new SubVariable();
  SubVariable sub = (SubVariable)parent;
  
  
  // 方法调用
  System.out.println(parent.getStaticStr());
  System.out.println(parent.getStr());
  
  System.out.println();
  
  System.out.println(sub.getStaticStr());
  System.out.println(sub.getStr());
  
  
 }
}

 

运行的结果为:

父类静态变量
子类实例变量

 

子类静态变量
子类实例变量

 

这里看出,当用实例方法访问实例成员变量时,不会出现数据的不一致;当然静态方法访问静态成员变量仍然会出现数据的不一致,因为静态方法不会被重写

 

3、同名不可见方法和成员变量不存在覆盖或隐藏问题

 

这一点讨论的实际上是变量的修饰符问题。如果父类同名成员或方法对子类可见,即可符合前面两句话;如果父类成员或方法对子类不可见的话,既然看不到,其实就不存在同名问题。如果子类硬要访问父类中不可见成员变量或方法,就会出现非法,编译报错。所以大可不必去深究同名成员变量或方法的修饰符问题,而只是可见和不可见的问题。

 

对java中同名成员变量和方法的覆盖和隐藏问题就讨论到这里。欢迎大家发表自己的观点!

 

6
2
分享到:
评论
4 楼 ayis 2008-07-31  
引用
从虚拟机指令的调用的角度来看:
对static方法、private方法、构造方法(实际上就是static的)、采用super调用方法这几种形式的调用都是编译期绑定的,也就是对这几种方法的调用只需看引用的类型。
而一般的方法都是采用运行时绑定,所以是看引用所指向的具体对象来调用相应的方法。
我的qq:276608415 欢迎多探讨


  确实你说得很对,我一直对这个地方都不理解。我只好把它当作java的一个缺点来理解了
3 楼 xinglongbing 2008-07-31  
从虚拟机指令的调用的角度来看:
对static方法、private方法、构造方法(实际上就是static的)、采用super调用方法这几种形式的调用都是编译期绑定的,也就是对这几种方法的调用只需看引用的类型。
而一般的方法都是采用运行时绑定,所以是看引用所指向的具体对象来调用相应的方法。
我的qq:276608415 欢迎多探讨



2 楼 lishali12345 2008-07-24  
确实很精辟!
值得一看!
看后深感有所获!
1 楼 臧圩人 2008-07-08  
总结的很好
欢迎来我的博客交流:http://zangweiren.iteye.com/blog/211278

相关推荐

    JAVA面试题解惑系列合集

    .8 1.3 JAVA面试题解惑系列(三)——变量(属性)的覆盖 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16 1.4 JAVA面试题解惑系列(四)——final、finally和finalize的区别 . . . . ...

    臧圩人--JAVA面试题解惑系列合集.pdf

    **1.3 JAVA面试题解惑系列(三)——变量(属性)的覆盖** - **知识点**:讲解Java中变量覆盖(或称为“隐藏”)的概念,即子类中声明与父类相同名称的变量时,子类变量在子类方法中优先访问。 **1.4 JAVA面试题...

    JAVA面试题解惑系列.rar

    Java面试题解惑系列主要涵盖了Java编程语言的核心概念、进阶技术以及在面试中常见的问题。这个压缩包可能包含了两本书籍,一本是"JAVA面试题解惑系列.pdf",另一本是"臧圩人--JAVA面试题解惑系列合集.pdf"。这些资源...

    《经典JAVA面试题解惑系列合集(臧圩人)》

    《经典JAVA面试题解惑系列合集(臧圩人)》这本书很可能就是针对这些问题进行深入解析的一本指南。 首先,Java的基础知识是面试中的必考部分。这包括但不限于Java语法、数据类型、控制结构(如if语句、for循环、...

    JAVA面试题解惑系列

    JAVA面试题解惑系列

    Java面试题解惑系列

    3、变量(属性)的覆盖;4、final,finally,finalize;5.传了值还是传了引用;6.String杂谈;7.日期与时间的处理;8.基本类型总结;9.继承,多态,重载,重写;10.多线程;11.运算符总结。 适合将要笔试面试Java的...

    JAVA面试题解惑系列——类的初始化顺序

    在Java中,类的初始化顺序是一个经常被问及的面试题目,尤其对于Java程序员和工程师来说,了解这个知识点是必须的。在Java中,类的初始化顺序是面试中的经典问题之一,它涉及到继承、静态成员以及实例成员等多个方面...

    JAVA面试题解惑系列(一)——类的初始化顺序-JAVA程序员JAVA工程师面试必看.pdf,这是一份不错的文件

    JAVA面试题解惑系列(一)——类的初始化顺序 JAVA 是一门面向对象的编程语言,类的初始化顺序是 JAVA 程序员和 JAVA 工程师面试中一个非常重要的知识点。本文将详细讲解类的初始化顺序,并提供了相关的测试代码,...

    JAVA面试题解惑系列.doc

    《JAVA面试题解惑系列——类的初始化顺序》 在Java编程中,理解类的初始化顺序是面试中常见的考察点,因为它直接关系到程序的执行逻辑。本文将深入探讨类的初始化过程,以及在继承场景下如何理解这个过程。 首先,...

    Java全能学习面试手册——互联网企业面试真题.zip

    Java全能学习面试手册——互联网企业面试真题.zip 01 java面试——北京-百度-Java中级.pdf 02 java面试——北京-京东-Java中级.pdf 03 java面试——广州-唯品会-Java大数据开发工程师.pdf 04 java面试——杭州-阿里...

Global site tag (gtag.js) - Google Analytics