A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张扬123 中级黑马   /  2012-8-14 22:15  /  2198 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张扬123 于 2012-8-15 09:27 编辑

看到一个例子:

public class Privateoverride {
  private void f() { System.out.println("private f()"); }
  public static main(String[] args) {
    PrivateOverride po = new Derived();
    po.f();
  }
}

class Derived extends PrivateOverride {
  public void f() { System.out.println("public f()"); }  
运行结果是:private f()
例子解释说是由于基类中的private方法对于导出类是不可见的
但是我不太明白,为什么动态绑定对于这个例子没有起作用?
谁给我详细解释下这个代码。我理解的肯定有错误。谢谢了。

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 赞一个!

查看全部评分

7 个回复

倒序浏览
多态中对象调用成员的特点
PrivateOverride po = new Derived();
               
A:成员变量
编译看左边,运行看左边
B:成员方法
编译看左边,运行看右边
C:静态方法
编译看左边,运行看左边

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 新人鼓励!

查看全部评分

回复 使用道具 举报
public class PrivateOverride
{
        private void f()//当这里private换成public打印的就是子类的方法即:public f();
        {
                System.out.println("private f()");
        }

           public static void main(String[] args)
        {
                PrivateOverride po = new Derived();
                     po.f();
        }
}

class Derived extends PrivateOverride
{
        public void f()
        {
                System.out.println("public f()");
        }
}

/*
这里就是权限问题了,
首先跟你说下子继承父类,成员函数编译看父类,运行看子类。

当时成员变量和静态成员函数编译运行都看左边。


你这个问题呢?

当jvm走到po.f();的时候就去父类找了然后发现父类有,(子类也有)

但是不能复写因为它是私有的,所以运行的就是父类的private 的方法。


*/

//希望楼主代码优良点。

点评

子类没有把f()继承过来,更谈不上复写,为什么就不执行子类的f()的?  发表于 2012-8-14 23:09

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 很给力!

查看全部评分

回复 使用道具 举报
王德升 发表于 2012-8-14 22:51
public class PrivateOverride
{
        private void f()//当这里private换成public打印的就是子类的方法即:pu ...

jvm会先去父类找,然后再去子类(就像初始化先初始化父类) ,你可以在父类定义一个成员变量,看看运行的结果是父类还是子类,当成员被private修饰了,子类出现同名的函数或者变量就会不能将其复写,所以运行的是父类的,即便子类的变量或者方法名相同。希望可以帮助到你,

点评

如果是先找父类的话,为什么两个都是public的时候执行的是子类的呢?  发表于 2012-8-14 23:48
回复 使用道具 举报
王德升 发表于 2012-8-14 23:25
jvm会先去父类找,然后再去子类(就像初始化先初始化父类) ,你可以在父类定义一个成员变量,看看运行的 ...

首先跟你说下子继承父类,成员函数编译看父类,运行看子类。
因为权限一样就可以复写了,
它私有不就是不对外公开吗 外界不可以访问啊。
回复 使用道具 举报
例子解释说是由于基类中的private方法对于导出类是不可见的。
因为 父类Privateoverride 中定义的f() 方法是一个private型的,所以说除了本类之外,其他任何类都不能访问到这个f方法。(当然也包括其子类了)。
为什么动态绑定对于这个例子没有起作用?
对于这个问题 毕老师曾经讲过的。我记得原话是这么说的:父类中的私有方法不可以被覆盖
虽然这么说的,但是你在子类中声明个和父类中这个私有方法一样方法时 编译也是可以通过,没问题可以运行。也就像你题中写的那样。对于这句话 我的理解就是 父类中的私有方法可以被子类所继承(但是不能直接方法父类中的private方法哦),如果在子类中试图重写这个私有方法,我就认为是重新又定义了一个新的方法,所以就不会构成多态了。也即多态那套规则对于“重写私有方法”(暂且这么错误地说)来说是没用的。
就那你的例子来说:
public class Privateoverride {
     private void f() {
       System.out.println("private f()");
    }
     public static main(String[] args) {
          PrivateOverride po = new Derived();
          po.f();
     }
}
class Derived extends PrivateOverride {
     public void f() { //虽然去“重写”父类中的私有的f方法,但并不构成覆盖重写。所以就跟动态绑定什么的没关系了。(我的理解就是)这是定义的不同于父类中f方法的一个新的方法。所以在处理这样的问题时,就拿一般方法来对待即可哦。
         System.out.println("public f()");
    }  
}


评分

参与人数 1技术分 +1 收起 理由
田建 + 1

查看全部评分

回复 使用道具 举报
public class PrivateOverride
{
        private void f()//当这里private换成public打印的就是子类的方法即:public f();
        {
                System.out.println("private f()");
        }

           public static void main(String[] args)
        {
                PrivateOverride po = new Derived();
                     po.f();
        }
}

class Derived extends PrivateOverride
{
        public void f()
        {
                System.out.println("public f()");
        }
}

我觉得问题应该这样考虑,成员方法编译时看左边,运行时看右边这句话肯定没问题,这道题也正是用这句话来解释的。怎么讲?
编译时看左边,那就是说父类引用调用的方法肯定是父类中有的方法编译才能通过的。即对象po中有f(),但是这个方法是私有的,说明子类没有继承过去,即子类中没有编译通过的这个f(),这样只能调用父类中的这个方法了。
回复 使用道具 举报
谢谢大家的回答,这个问题毕老师讲过的。一时糊涂。问题已解决。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马