子类继承父类private属性问题
子类可以继承父类的private属性,但是不能访问。具体到以下这个程序如何解释呢?class Person {
        private String name;
        private int age;
        public void setName(String name) {
                this.name = name;        
        }
        public void setAge(int age) {
                this.age = age;
        }
        public String getName() {
                return name;
        }
        public int getAge() {
                return age;
        }
}class Student extends Person {
        private String school;
        public void setSchool(String school) {
                this.school = school;
        }
                public String getSchool() {
                return school;
        }
}public class TestPerson {
        public static void main(String[] args) {
                Student student = new Student();
                student.setName("John");
                student.setAge(18);
                student.setSchool("SCH");
                System.out.println(student.getName());
                System.out.println(student.getAge());
                System.out.println(student.getSchool());
        }
}我在网上搜索有如下两种解释:
(1)
子类是不能访问父类中private的属性和方法的,但子类能访问父类的public的属性和方法,因为student这个类继承父类Person,而父类Person里的setName()是public的,所以子类能访问setName()这个方法,setName()这个方法又是在父类Person里的,在同一个类里的方法当然可以访问这个类的属性,总的来说:就是子类student通过setName()来间接访问父类Person的私有属性(2)
子类虽然不能访问父类的私有变量,但是子类继承了父类的变量和方法,Student类实际上有3个变量,分别是name age school,有6个方法,分别是父类的4个和自己的两个,实际上你在main方法是给自己的private变量name age school 赋值,所以你在get时取到的是自己的private 变量值 而不是父类private变量的值
Student子类究竟是访问Person父类的东西,还是访问自己的东西呢?以上哪种解释更合理呢,因为这是基础,得弄明白,请教各位大虾们了!~感激~

解决方案 »

  1.   

    第二种解释看不明白是要说明什么,如果非得要说这个私有属性是谁的,好像就变成了私有属性到底能不能被子类继承这个经典的问题。
    其实是一个很简单的道理就是通过set get方法来访问private属性,这是公认的做法
      

  2.   

    第一种说法较为合理,但这种情况在实际开发过程中纯在明显的缺陷,自相矛盾
    既然那两个属性是父类私有的属性,一般来说就不会再去公开的写一个set和get方法,此属性只能属于父类,子类继承父类,只能获得到父类公开的方法和属性。
      

  3.   

    声明get/set方法,有时候可以只有get方法,而没有set方法,只允许获得而不允许设置值的时候,属性就得是private,再写个get方法
      

  4.   

    从创建实例对象时构造函数的工作方式可以这么理解
    先把父类构造好,给属性(不管私有否)开辟空间
    再包层 外边加上子类的属性
    最后成一个对象
    只是处于内部的那些父类的私有属性
    子类没有直接的调用权
    通过 set get 函数进行操作
      

  5.   

    楼主这个问题我也发过贴子问过,其实我们可以这样来理解,可能我的想法不是很成熟,希望各位大鸟多多指教当一个子类继承一个另一个类以后,当我们重写父类中一个方法的时候 再调用父类被重写的这个方法的时候 
    很明显这个方法没有改变 这就说明一个问题 那就是当一个子类继承一个父类的时候 相当于把父类所有的方法
    和属性都复制一份过来了  在复制过来的这些方法和属性中对于public修饰的属性和方法对于子类来说是可见
    的 但是对于private修饰的父类的私有变量来说就是不可见
    不知道这样理解对不对 各位大鸟多多指教啊
      

  6.   

    从jvm考虑吧,你看看继承是咋实现的就知道了
      

  7.   

    他继承了这个私有属性又怎么样,还是不能直接访问,继承了这个私有属性又怎么样,我们可以通过get/set来访问
      

  8.   

    student类继承自Person类,那就拥有了自己的继承自父类的方法。在测试类中使用Student类的对象调用的是Student类继承自Person类的自身的方法。这里的关键在于对继承的理解。这里父类的私有属性肯定是不能通过super.xxx(父类的私有属性)这样直接访问,但是可以通过父类的Public接口提供访问。在此处测试类中,定义一个Student对象然后对Student的方法进行操作和访问,肯定是和父类中的方法和属性不相关的。
      

  9.   

    就是通过public方法操作父类的属性,可以话内存分析图来分析~
    其实本质是:创建Student 类时 先调用Person类的构造方法先把父类创建出来,然后再调用Student 的构造方法把自己创建出来,其实Student 对象中包含一个Person 的属性和方法。你就理解为大圈(Student)里面有个小圈(Person)。就是这样,两种说法都可以说是对的,只不过是占的角度不同。
    你就记住就是通过public方法操作父类的属性就对了~~
      

  10.   

    很多人都给出了第一种的解释。
    我现在说说第二种的不合理处。
    第二种说父类的private属性其实是属于子类的。
    那么你在子类直接去拿父类的private属性显然是会报错的
    所以父类的private属性并不属于子类
      

  11.   

    这句话有问题..个人觉得应该是说:子类不能继承父类的私有属性.但是可以访问私有属性..是否继承就用super点下就知道继承了那些...私有的是点不出来的.
    所以说:能被访问的不一定是被继承的属性.被继承的属性是一定能被访问.....
      

  12.   

     我们在编写类的时候,大部分是把变量写成private的吧。这是安全的考虑
    “子类可以继承父类的private属性,但是不能访问”
      这里的不能访问,是不能直接调用 如super.父类的属性 ..这样做是违法的。。
      private 是安全的考虑,不是不能用 是不能直接用。。 所以就有了 get/set这样的public的方法。这样
    子类就可以用父类的属性。。但是前提父类有 get/set方法。
      还有 类生成对象的时候 父类也是被申明了的 里面的属性也是有内存空间的。。 第一种说法中的
      “就是子类student通过setName()来间接访问父类Person的私有属性,这里的setName()方法是调用的父类的,那么自己调用自己的私有是没有问题的, 如果你在子类中覆写这个方法的话。。你可以试下能不能调用。”
      第二中说法 
      “Student类实际上有3个变量,分别是name age school,”
       如果是自己的变量,无论访问的权限是什么, 自己的方法中不就可以this.属性 调用了吗,但是(private的)不能这样做。
      所以不能简单的认为就是自己的属性。而是从父类那里继承过来的属性   
       
      

  13.   

        其实是Student继承了Person里面的Public方法  而在mian方法里面调用get/set方法  只是利用它Person的Get/Set方法去访问它自身的私有属性   
      

  14.   

    Student所访问的name和age是Person的。
    因为创建Student类的对象时,会调用父类无参数的构造方法,

    public Student()
    {
      Super();
    }
    既然调用了父类的构造方法,因此堆中就有了Person的对象,
    也就是说name和age已经分配了内存空间,而setXXX()和getXXX()是public的
    Student能够继承,通过它们可以访问Person的name和age。
      

  15.   

    你在子类Student中写一个
    private int age
    然后再弄一下set、get方法,看看是不是跟你继承自父类的方法效果一样不就得了。 private int age; public int getStudentAge() {
    return age;
    } public void setStudentAge(int age) {
    this.age = age;
    }看看setStudentAge()与setAge()哪个有效就知道了。
      

  16.   

    是不能直接访问继承的私有属性,但是可以通过继承的公有getter setter去访问.我也不理解
      

  17.   

    我觉得这个问题。。 也不是什么大的问题、、 现在也许理解不对 是因为自己没有遇到过这种问题。
        JAVA编程有语言规范的。。 自己尝试着按照那个规范做就好。。
      等自己遇到问题的时候。。 自然会理解
      
      

  18.   

    他的set/get是公有类型的,当然可以访问了
      

  19.   


    class Person {
        private String name;
        private int age;
        public void setName(String name) {
         System.out.println(this.getClass().getName());//加一句输出就知道了
            this.name = name;        
        }
        public void setAge(int age) {
         System.out.println(this.getClass().getName());//加一句输出就知道了
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
    }
    //子类继承了父类所有的属性和方法,只是访问权限的问题。
      

  20.   

    这问题就很奇怪!如果子类能访问父类 private 字段,那 protected 有什么用?从字面意义就能看出 private 的东西除了在自己类中(类声明的“{”到结束的“}”之间)可以访问之外,其他地方都访问不了。
      

  21.   


    这不是经典问题,而是月经问题!1:那个不叫“属性”,应该称为“成员变量”或“字段”。在 Java 中“属性”指的是根据 JavaBeans 规范从 get/is/set 方法获得的名称。2:你理解的继承是子类对象从父类对象中原原本本地复制过来一份,实际在 JVM 中并不是这样的。
      

  22.   

    竟然说是private的即是说除了自己没有任何其它的类可以访问了,对于其它的类相当于不存在了还说啥呢?
      

  23.   

    lz啊,
    首先,private修饰符是什么意思呢?意思是只能在同一个类内才能访问,java语言的语法就是这样,如果你要想被子类访问,那你该给他public修饰父类属性,即使不是这样,那你也改给protected吧。
    然后,extends是继承父类的属性和方法,Student的属性是和父类的属性所在内存位置是不一样的,别混淆了
    最后,这是我的领悟,还待续考证,有什么不对,请指出
      

  24.   

    private定义的字段只能在本类中使用,如果其他类中需要访问就要用set()和get()方法。大家为何为这种问题纠结?
      

  25.   

    子类继承了父类
    既然是你父类的私有属性,就说明这个属性只在父类中,就好像你父亲喜欢画画,而你继承了他喜欢画画的好爱,而你父亲特有的特性是画老虎,而你的是画猫。
    看看下面的代码你应该就明白了。
    class Person {
            private String name = "老爸的名字";
            private int age;
            public void setName(String name) {
                    this.name = name;        
            }
            public void setAge(int age) {
                    this.age = age;
            }
            public String getName() {
                    return name;
            }
            public int getAge() {
                    return age;
            }
    }class Student extends Person {
            private String school;
            public void setSchool(String school) {
                    this.school = school;
            }
                    public String getSchool() {
                    return school;
            }
    }public class TestPerson {
            public static void main(String[] args) {
                    Student student = new Student();
                    student.setName("自己的名字");
                    student.setAge(18);
                    student.setSchool("SCH");
                    System.out.println(student.getName());
                    System.out.println(student.getAge());
                    System.out.println(student.getSchool());
            }
    }
    输出的肯定的是你 自己的名字 不可能是老爸的名字。
      

  26.   

    去查一下JavaBean的概念就清楚了
      

  27.   

    浪费时间的问题:java面向对象的一个重点就是封装:子类是不能继承父类的私有成员变量也就不能引用了(指的是用super.XXX去直接改变这个成员变量的值,如果我们需要子类来引用这个内部的私有变量我们可以提供一个开放的接口:也就是方法,在这个方法里我们可以加上我们的一些限制。)这个问题是子类继承了父类的开放接口,然后由父类的自己的方法去间接的访问它自己的内部私有变量而已。
      

  28.   

    私有属性会被子类继承的。
    为啥呢?继承是“is a”,也就是说子类is a 父类,所以他有父类的所有内容。包括行为。
    父类有成员X,子类就有成员X
    父类有方法X,子类就有方法X
    如果说成员X是私有的,子类不能访问,违反了 子类有成员X 的理论,那其实是理解错误。 我有xxx,不等于我可以访问、操作、修改、删除...这个东西,就像我有住房公积金一样,但是我不能拿到钱,只有公务员可以随便花;子类也不能访问父类没有的特性,访问私有成员就是这样。 
    但是,既然是子类,也不是完全没有办法访问,就好比公积金一样,也不是完全没有办法
    方法一,遵循指定的方法;取公积金可以通过购房等,拿到发票和证明,依据各个城市的公积金管理办法就可以拿到一部分了,这个在java里就是通过访问父类公开的接口来实现;
    方法二,你也可以通过代理,走一些不那么光明正大的途径来拿到公积金,因为他们有关系,当然,你需要付出一些代价;在java,就是反射,你可以用反射,随便访问私有成员,但是要付出代价(性能代价),而且你要有关系(你必须知道反射API)