黑马程序员技术交流社区

标题: 帮忙分析一个程序 [打印本页]

作者: 郑冬    时间: 2012-6-13 19:18
标题: 帮忙分析一个程序
本帖最后由 郑冬 于 2012-6-19 13:08 编辑

下面的程序,为什么不能通过编译?
class  Base
{
    public String classname= "Base";
}
class Derived extends Base
{
    private String className = "Derived";
}
public class PrivateMatter
{
    public static void main(String [] args)
    {
         System.out.println(new Derived().className);
    }
}
作者: 郑传庆    时间: 2012-6-13 19:28
class Base {
        public String classname = "Base";
}

class Derived extends Base {
        public String className = "Derived";//改成公有的
}

public class PrivateMatters {
        public static void main(String[] args) {
                System.out.println(new Derived().className);//className不能定义为私有的,定义为私用的,外部的类就访问不了
        }

作者: 郑冬    时间: 2012-6-13 19:36
郑传庆 发表于 2012-6-13 19:28
class Base {
        public String classname = "Base";
}

我刚开始也认为错误在这,以为是Derived中的className变量比Base中的className变量有更高的访问限制权限,可是问题好像不在这
作者: 田林    时间: 2012-6-13 19:37
private修饰的对象只能在本类中调用
作者: 淡然    时间: 2012-6-13 19:38
子类的private变量覆盖了父类的public成员变量,但是
父类由于private变量受访问权限的限制,它不能被覆盖。
属性的值取父类还是子类并不取决于我们创建对象的类型,而是取决于我们定义的变量的类型。
friendly、protected和public修饰符并不影响属性的覆盖。
静态变量和静态常量属于类,不属于对象,因此它们不能被覆盖。
常量可以被覆盖。
对于基本类型和对象,它们适用同样的覆盖规律。
  1. class  Base
  2. {
  3.     public String classname= "Base";
  4. }
  5. class Derived extends Base
  6. {
  7.     public String className = "Derived";
  8. }
  9. public class PrivateMatter
  10. {
  11.     public static void main(String [] args)
  12.     {
  13.          System.out.println(new Derived().className);
  14.     }
  15. }
复制代码

作者: 伊文龙    时间: 2012-6-13 19:49
首先,你的子类的属性和父类的属性同名,父类中的属性就被隐藏起来了。不再起作用。
然后,你的子类属性是用private修饰的。只能被本类对象访问到。
作者: 郑冬    时间: 2012-6-13 19:52
淡然 发表于 2012-6-13 19:38
子类的private变量覆盖了父类的public成员变量,但是
父类由于private变量受访问权限的限制,它不能被覆盖 ...

如果className是一个方法,那么如你所说应该是对的,可是这里className并不是一个方法,而是一个字段,所以Derived.className是隐藏了Base.className而不是覆盖了它,隐藏字段的访问权限比被隐藏字段的少,好像是合法的吧
作者: 郑冬    时间: 2012-6-13 19:52
所以我觉得问题应该不是出在这

作者: 郑传庆    时间: 2012-6-13 19:59
郑冬 发表于 2012-6-13 19:36
我刚开始也认为错误在这,以为是Derived中的className变量比Base中的className变量有更高的访问限制权限 ...

不是吗?不管内部类还是外部类,如果一个类要想访问其它的类的成员都要定义成公有的
作者: 王红霞    时间: 2012-6-13 20:19
在PrivateMatter类中的System.out.println(new Derived().className)语句使用了类Derived的对象,而Derived类中的对象是私有的,不能使外面的类使用它的对象。
作者: 郑冬    时间: 2012-6-13 20:28
恩,我知道了,如果把Derived中的className的访问权限设定为private,则PrivateMatter是不能访问的,尽管Derived中的Base.className被隐藏了,是不是可以通过System.out.println(((Base)new Derived()).className);访问它呢?
作者: 王明明    时间: 2012-6-13 20:40
本帖最后由 王明明 于 2012-6-13 20:47 编辑
  1. class  Base
  2. {
  3.     public String classname= "Base";
  4. }
  5. class Derived extends Base
  6. {
  7.     public String className = "Derived";
  8. }
  9. public class PrivateMatter
  10. {
  11.     public static void main(String [] args)
  12.     {
  13.          System.out.println(new Derived().className);
  14.     }
  15. }
复制代码
的却是你 定义了私有问题
假如你编译不通过的话 错误应该提示了你 PrivateMatter 是公共类 应该把文件命名为 PrivateMatter.java
或者你把public class PrivateMatter 不要定义成公共的了class PrivateMatter
就这样
定义私有的变量 你要访问的话 你可以在本类里面建立一个方法 复制给变量
然后通过方法来对外提供私有变量的方法 在面向对象的视频里面 第五天的 有讲到 你可以温故一下
作者: 郑冬    时间: 2012-6-13 20:59
王明明 发表于 2012-6-13 20:40
的却是你 定义了私有问题
假如你编译不通过的话 错误应该提示了你 PrivateMatter 是公共类 应该把文件命名 ...

好的,我回头复习一下
作者: 邓杰    时间: 2012-6-13 21:28
这个代码只有两个地方可能是你通不过原因:1 就是提示你 PrivateMatter 是公共类 应该在名为PrivateMatter.java的文件中申明;
第二就是private的问题;JVM已经说的很清楚了       ^
Base.java:14: className 可以在 Derived 中访问 private
         System.out.println(new Derived().className);//被 private修饰的成员只能在本类调用;这就是private和public的区别啊;权限修饰符嘛。再补下;
作者: 赵倩倩    时间: 2012-6-13 22:37
对于编译不通过就是在Derived中成员的权限问题  应该是public ,不应该是 private String className = "Derived";
至于继承方面 子类对其进行重写,就是子类赋予的值  所以错误就是在私有
public class PrivateMatter
{
    public static void main(String [] args)
    {
         System.out.println(new Derived().className);//这里就是在另一个类PrivateMatter中引用外部类中的成员要用外部类的对象进行引用
    }
}
作者: 郑冬    时间: 2012-6-13 22:38
谢谢补充,弄清楚了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2