http://topic.csdn.net/t/20051011/22/4320354.html,在此篇文章中,lyj830223(少年游),说了下面一句话:--------------------------------------------------
樓上的,強!   
  說的很對。   
  組合是在一個類中引用另一個類。生成另一個類的實例。   
  而继承只是继承了父类的变量和方法。   
  区别:   
  使用组合可以用到另一个类中私有的变量和方法,而继承就不可以用到父类的私有的变量和方法了   
  他们都有各自的好处,要灵活的运用。   
--------------------------------------------------这段话中有一句:使用组合可以用到另一个类中私有的变量和方法,而继承就不可以用到父类的私有的变量和方法了“继承一个类后,是否可以使用父类的私有属性/方法”,对这一问题一直模糊不清,于是,自己想了下面的例子:
A.java:package p1;public class A {
private int a1 = 1;
int a2 = 2; int getA1() {
return a1;
} int getA2() {
return a2;
}
}
B.java:package p1;public class B extends A {
public void test() {
// System.out.println(this.a1); // 访问不到a1属性,强制在这里打上此条语句,MyEclipse提示:The field A.a1 is not visible
System.out.println(this.getA1()); // 我认为:可以访问到getA1()方法,但是,getA1()方法访问不到a1属性,是不是这样呢? System.out.println(this.a2); // 可以访问到
System.out.println(this.getA2()); // 可以访问到
} public static void main(String[] args) {
B b = new B();
b.test();
}
}
运行B类,结果:1
2
2即:System.out.println(this.getA1());,此条语句的打印结果是:1
听到过很多人都有一种说法:私有属性/方法不能被继承。我也一直这么认为,现在就按照“私有属性/方法不能被继承”这一观点来分析,A类,有2个属性:
a1属性 private的
a2属性 默认的2个方法:
getA1() 默认的
getA2() 默认的
B类,有0个属性:2个方法:
test()
main()
因为私有属性/方法不能被继承,所以,B类继承A类后,B类,有1个属性:
a2属性4个方法:
test()
main()
getA1()
getA2()B类继承了A类,继承过来的属性/方法就是自己的了,所以,继承A类后,B类自己的属性、方法就是a2属性、test()、main()、getA1()、getA2()方法。此时,我们在B类的test()方法中一点,出来一个列表:a2 int - A
clone() Object - Object
equals(Object obj) boolean - Object
finalize() void - Object
getA1() int - A
getA2() int - A
getClass() Class<? extends Object> - Object
hashCode() int - Object
notify() void - Object
notifyAll() void - Object
test() void - B
toString() String - Object
wait() void - Object
wait(long timeout) void - Object
wait(long timeout, int nanos) void - Object
main(String[] args) void - B
从Object类继承过来的方法这里不考虑,整理一下,继承A类后,B类自己的属性、方法如下:
a2 int - A
getA1() int - A
getA2() int - A
test() void - B
main(String[] args) void - B
此时,在B类的test()方法中,用this.getA1()访问的是B类自己的getA1()方法,而A类的a1属性没有继承过来,所以,在调用执行getA1()方法时,就应该出错(a1属性未定义),可是却没有,而是打印出了A类的私有属性a1的值:1。这是为什么?我是这样认为的:“私有属性/方法不能被继承。”这个说法是错误的,私有属性/方法是可以被继承的,只是继承过来之后,是不可见的而已。拿上面的例子来说:B类继承了A类后,B类自己的属性、方法如下:(a1 int - A) A类的私有属性a1继承过来了,只是隐藏不可见而已。
a2 int - A
getA1() int - A
getA2() int - A
test() void - B
main(String[] args) void - B
然后,在B类的test()方法中,this.getA1()调用执行了从A类继承过来的、自己的getA1()方法,在此方法体中返回了继承过来的的私有属性a1的值:1。
以上是我的理解。
想问大家的问题:问题1: B类继承A类后,A类的私有属性a1有没有继承过来?我的观点:已经继承过来了,B类的test()方法中:System.out.println(this.getA1());此条语句打印出:3其中的this.getA1()方法,返回的是从A类继承过来的、已经是B类自己的私有属性a1的值,而返回的不是属于父类的私有属性a1的值。
以上所有理解错误的地方,还有第1个问题,希望大家指点,谢谢大家。

解决方案 »

  1.   

    子类拥有基类的所有属性和方法,只是private属性不可见
      

  2.   

    er.....
    我觉得在这个列子中实质只是在A类中只是提供了访问a1的方法....int getA1()...这个就好像get set方法一样吧...如果A类的int getA1()不返回a1的话,
    有什么方法可以访问a1呢?
      

  3.   

    问题1: B类继承A类后,A类的私有属性a1有没有继承过来? 我的观点: 已经继承过来了, B类的test()方法中: System.out.println(this.getA1()); 此条语句打印出:3 其中的this.getA1()方法,返回的是从A类继承过来的、已经是B类自己的私有属性a1的值,而返回的不是属于父类的私有属性a1的值。 
    以上所有理解错误的地方,还有第1个问题,希望大家指点,谢谢大家。 ----------------------------------------------------------------
    我说一下我个人的看法,
    由于b类继承a类,
    他继承了a类的getA1()的方法,
    但没有继承他的
    private int a1 = 1
    a1这个属性之所以在b类中能用
    System.out.println(this.getA1());取出来的值,是用了向上转型的原因,,
    jvm先在b类里面找有没getA1()这个方法,发现没有的时候就转到了他的父类去了
    这个时候的this指的是a类,,
    你用
    System.out.println(this.getA1());
    打印出来了值,实际上是
    a。getA1()取出来的
      

  4.   

    我认为B在实例化的时候是要先执行A的构造方法,也就是说有A的对象了,所以当你用A的get方法时就能取到A的private属性变量了。PS:本人初学,以上是个人观点!
      

  5.   

    “私有属性/方法不能被继承。”  
     
    父类的私有成员的确可以被子类继承过去,是存在的,
    但是,它在子类中是不可见的,
    既然不可见,在子类中任何直接访问它的方式都是徒劳的,
    可是这并不代表父类的私有成员不能访问,而楼主的实验也恰恰说明了这一点
    也就是说可以通过父类的非私有方法去访问它,
    “然后,在B类的test()方法中,this.getA1()调用执行了从A类继承过来的、自己的getA1()方法,在此方法体中返回了继承过来的的私有属性a1的值..."对于楼主这句话说的意思,我觉得不太妥当,我感觉就是像7楼说的那样,就是直接调用的类A的方法,
    因为似乎只有通过类A的非私有方法才能访问它自己的私有成员.
    况且因为getA1()中有return a1;这一句代码,
    所以实际上getA1()在类B中其实也是不可见或者说是不可用的,大体我就是这样理解的...
      

  6.   

    真的不知道楼上这么多高手讨论这个问题,都应该去复习一下java访问权限的知识。楼主的代码是有问题的
    package p1;public class A {
        private int a1 = 1;
        int a2 = 2;    int getA1() {
            return a1;
        }    int getA2() {
            return a2;
        }
    }
    请问,getA1()方法前面没有加private 关键字,它怎么是私有属性/方法呢?这是默认访问权限,也就是包访问权限,他的意思是在同一个包内的类可以访问,楼主的代码中B和A是在同一个包内的,所以B中可以使用this.getA1()方法,把B移到别的包里试一试看呢!
    不要把私有访问限制和保访问限制搞混了在getA1(),getA2()方法前加上private 才是私有属性/方法,试试看加上private后,B能不能使用this.getA1()方法阿。这就是为什么System.out.println(this.a1);  这句代码不能用的原因。
      

  7.   

    是呀,你的开发工具都提示了:The field A.a1 is not visible
    只是不可视而已,并没有说没有定义这个变量··
      

  8.   

    java的一个特点是封装,就是把属性定义为private,想访问这个属性的话只能定义一个非私有的方法,通过这个方法访问,当然,为了体现封装,这个方法的返回值是可以通过改装的,就是我想让外界看到我的那个属性是什么样子,我就在这个方法里设置,例如我原来private int a = 1;然后我定义个一方法返回a,int geta(){retrun a+1;}这样外界看到的a就不是我原来那个了;楼主的子类肯定继承了方法getA1();,但这个方法是可以访问父类的私有属性的,你即使是随便一个类,在那个类里也可以通过new一个A类型的对象,通过该对象的getA1方法访问到A的私有属性,那这说明那个私有属性不私有了?楼主需要反思!!!!!当然,这是个人见解,不一定对的
      

  9.   

    JAVA里默认的方法限制关键字不写,相当于C++中的 friendly
    子类是可以继承访问的
      

  10.   


    答:类B继承类A,这意味着什么?首要一点是:类B的对象(即儿子的对象)中,完整地含有父亲类A的对象。即:儿子中有一份完整的父亲(含父亲中的属于对象的private成员)。就像洋葱一样,一层包一层。但这个private int a1儿子是看不见的,是不能直接访问的。只能间接访问。如:你的this.getA1()就是间接访问这个private int a1的。
      

  11.   

    答:因此,在设计类的时候,我们通常的原则是“数据成员首先考虑要隐藏(如:定义成private)”,然后再定义针对这些private 型数据成员的settet/getter(即:访问器)。楼主的getA1()就是一个访问器。访问器最好定义成public
      

  12.   

    private int a1 = 1;
    这里注明了是私有的变量,同一包内也不能访问    int getA1() {
            return a1;
        }    int getA2() {
            return a2;
        }
    这里没写,表示友元方法
    就是同一包内可访问通过友元方法访问私有变量,是没有问题的不明白的,可以看看单例模式,原理一样
      

  13.   

    B 继承了 A 中所有的东西,包括私有属性和私有方法。实际上在 B 中也有两个属性 a1 和 a2,由于访问修饰符的关系,a1 属性在 B 中是不可见的,
    也就是说不能直接访问的
      

  14.   

    真的搞笑,LZ有没有搞清楚private和public这些关键字叫什么?叫访问修饰符
    封装,继承,多态,好好复习下
      

  15.   

    在JAVA中你没有加访问修饰符的话默认为default
      default可被同包中的任意的子类访问
    这就是你为什么能访问到
            System.out.println(this.getA1());
            System.out.println(this.a2); 
            System.out.println(this.getA2());
      

  16.   

    私有就不能访问的话···还要final做什么···
      

  17.   

    好多回复`看的我是眼花缭乱啊!A B 两个类在同一个包中A类中有一个私有的变量a1,其余的变量和方法都是defalut,那么除a1变量不能被外界访问剩下的方法与属性在同包的情况下外界可以访问!B继承A,且在同一包中!B继承了A类中所有方法与属性(包括private),为什么呢?我来做个分析:比如:子类对象B 指向父类(向上转型)如果没有继承,岂不是要出严重的内存错误了?private 只是一个访问修饰符号! 只是不能访问而已!
      

  18.   

    7 楼的解释是正确的。1 私有属性没有继承问题,因为子类根本不知道是否有这个属性。
    2 你调用了一个方法,而这个方法子类并没有实现,是父类实现的,而父类当然能使用它自己的私有属性了。
    3 如果你在子类重写了那个方法,请看:
    class B extends A {
      int getA1() {
        return a1; ///////??? 这里用属性,怎么写都没戏
      }无论是 a1,super.a1 都没戏,只有
    return super.getA1();可以!
      

  19.   

    答:说得对!问题讨论的真正核心是:“继承”这个术语到底按如下那一种进行解释
    “对继承术语的”第一种解释:父类中所有的子类能够访问得到的成员,才能被“继承”。(当然,构造器除外)这个解释是许多人的看法。但:这个看法可能带有的付作用是:容易认为父类中的private成员,子类对象中不包含它们的“错觉”。事实上:子类对象中包含有一个完整的父对象。
    “对继承术语的”第二种解释:父类中所有的成员子类都“继承”下来(当然,构造器除外),但父类中的private成员,子类对象不能访问它们(即:33楼所说的:有拥有权,无使用仅)。这个解释带来的好处是:说明了子类对象包含了父类对象中所有的成员这一个事实。但[color=#FF0000]不好之处[/color]是:容易认为:你既然都已“继承”下来了,你来使用使用看?(即:34楼的观点)你们认为,“继承”这一个术语,到底按哪一种“解释”来理解?
      

  20.   

    多态这部分真是怎么讨论都不烦,啥怪事都会有。我说一下我的理解吧:
    在声明子类的实例的时候,会先实例化父类的对象,
    然后在这个父类的对象的基础上再去扩充,以此达到实例化子类对象的目的。
    可以理解成,子类对象里面包着一个父类的实例。
    因为那两个方法是default
    的。所以被子类继承了下了,虽然被继承了下来!可是这两个方法仍然是属于父类的!
    子类只不过是可以调用而已!千万不要以为继承了下来就表示子类里就有了同样的方法!(这就成了重写了)
    所以你在调用这两个方法的时候,实际是在调用被包在子类里的那个父类的实例的方法!
    既然调用的是父类的实例的方法,那在父类的实例里自然就可以访问父类实例的私有成员了!至于私有属性到底有没有被继承,我忘了,我认为是没有被继承!如果哪里说错了,还请指正!
      

  21.   

    http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#29882看不太明白 牛人可以来解释下2.8.4 The Class Members
    The members of a class type include all of the following: Members inherited from its direct superclass (§2.8.3), except in class Object, which has no direct superclass.Members inherited from any direct superinterfaces (§2.13.2).Members declared in the body of the class. 
    Members of a superclass that are declared private are not inherited by subclasses of that class. Members of a class that are not declared private, protected, or public are not inherited by subclasses declared in a package other than the one in which the class is declared. Constructors (§2.12) and static initializers (§2.11) are not members and therefore are not inherited.2.9 Fields
    The variables of a class type are its fields. Class (static) variables exist once per class. Instance variables exist once per instance of the class. Fields may include initializers and may be modified using various modifier keywords. 
    If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in the superclasses and superinterfaces of the class. A class inherits from its direct superclass and direct superinterfaces all the fields of the superclass and superinterfaces that are accessible to code in the class and are not hidden by a declaration in the class. A hidden field can be accessed by using a qualified name (if it is static) or by using a field access expression that contains a cast to a superclass type or the keyword super.
      

  22.   

    答:你说:“如果继承了就是自己的,要不然怎么叫继承,”。按你的这个说法,就有问题了:问题在哪?在于:子类对象中包含有一份完整的父亲。即:整个这个内存块都是子类对象的!连父对象中的private都在这个内存块中。即然这一切都是子类对象内存空间中的,还不是属于自己的吗?按你的说法,属于自己的,就是“继承”,这不就是矛盾吗?
      

  23.   

    答:我完全同意39楼提供的英文资料中的说法。谢谢classnameextendsjava兄弟提供资料!即:35楼中的“继承”术语的第一种解释
      

  24.   

    对 继 承 的 重 新 感 悟 :有一件事情我们首先要搞清,“继承”这个概念究竟是什么意思?以前听老师讲过:继承的好处有:1、减少了代码量。2、程序可读性增强。3、使程序更易维护。
    (对于第3点,老师举了一个例子,要表达的意思是这样的:class P {
    public void display() {
    System.out.println("我是一个程序员!");
    }
    }
    有5个类P1、P2、P3、P4、P5继承此类:class P1 extends P {
    ...
    ...
    ...
    }class P2 extends P {
    ...
    ...
    ...
    }class P3 extends P {
    ...
    ...
    ...
    }class P4 extends P {
    ...
    ...
    ...
    }class P5 extends P {
    ...
    ...
    ...
    }这样,当想在P1、P2、P3、P4、P5这5个类中将输出的话变为:
            我是一个老实的程序员!
    时,不需要在P1、P2、P3、P4、P5类中都修改代码,而只需要在超类P这一个类中修改一下代码即可。)
    所以,我的心里一直认为:P1、P2、P3、P4、P5类继承了P类,实质就是P类中的所有代码在P1、P2、P3、P4、P5类中被复制了一份,即:P1、P2、P3、P4、P5类继承P类后,就变成了:
    class P1 extends P {
    public void display() {
    System.out.println("我是一个程序员!");
    }
    ...
    ...
    ...
    }class P2 extends P {
    public void display() {
    System.out.println("我是一个程序员!");
    }
    ...
    ...
    ...
    }class P3 extends P {
    public void display() {
    System.out.println("我是一个程序员!");
    }
    ...
    ...
    ...
    }class P4 extends P {
    public void display() {
    System.out.println("我是一个程序员!");
    }
    ...
    ...
    ...
    }class P5 extends P {
    public void display() {
    System.out.println("我是一个程序员!");
    }
    ...
    ...
    ...
    }
    即是说:这5个子类中都写了一份display()方法的定义的代码,只是隐藏不显示出来而已。
    当我们将P类的代码修改为:class P {
    public void display() {
    System.out.println("我是一个老实的程序员!");
    }
    ...
    ...
    ...
    }
    时,编译器就会将P类中的代码重新复制一份到它的子类中,使子类变为:
    class P1 extends P {
    public void display() {
    System.out.println("我是一个老实的程序员!");
    }
    ...
    ...
    ...
    }class P2 extends P {
    public void display() {
    System.out.println("我是一个老实的程序员!");
    }
    ...
    ...
    ...
    }class P3 extends P {
    public void display() {
    System.out.println("我是一个老实的程序员!");
    }
    ...
    ...
    ...
    }class P4 extends P {
    public void display() {
    System.out.println("我是一个老实的程序员!");
    }
    ...
    ...
    ...
    }class P5 extends P {
    public void display() {
    System.out.println("我是一个老实的程序员!");
    }
    ...
    ...
    ...
    }
    继承是什么意思?答:对于此例来说,5个子类P1、P2、P3、P4、P5继承父类P中的display()方法,就是P类中定义display()方法的代码复制了一份到P1、P2、P3、P4、P5类中,这样,这5个子类各自就拥有了自己的display()方法,这就是继承的意思。以前,对于继承,一直是这样理解的。昨天问了老师,新的理解如下:观点1:
    P1、P2、P3、P4、P5类虽然继承了P类,也决定不会将父类P中的display()方法的定义的代码复制过来,那样在内存中就变成了6份,内存中会存6份完全相同的display()方法的定义的代码吗?如果会,那如果有1亿个子类继承P类,内存中岂不是会有1亿零1份display()方法的定义的代码,Java会这么做吗?答:不会,因为Java不会傻成这样。
    观点2:
    5个子类P1、P2、P3、P4、P5继承了父类P中的display()方法后,display()方法就是自己的了,因为已经继承了父类,当然display()方法就已经继承过来了,当然就成为自己的了。答:此观点错误,如果是这样,那1亿个子类继承了父类P,那这1亿个子类中就都有1个属于自己的display()方法吗?如果是这样,那加起来一共就是1亿零1个display()方法,不会是这样的,事实是:5个子类P1、P2、P3、P4、P5虽然继承了父类P中的display()方法,且能够在自己的类中使用此方法,但是,此方法依然不是自己的,无论有多少个子类继承父类P中的display()方法,在内存中display()方法只有1份。“继承”的意思不是说:“继承之后就变成你自己的了”,这个方法依然还是父类P的,所有的子类中在使用此方法时,使用的是同一(注意“同一”二字)个方法。(
    比喻:公园,我们每个人都可以在里面走路、享受,上午我将整个公园走了一遍,下午,我又走了一遍,还有许多人也是这样。但是,我们不能说是自己的公园,是我们共同的公园,只有1个公园。
    )那继承了P类的5个子类P1、P2、P3、P4、P5,我们知道,它们都可以使用display()方法,是如何使用的呢?看代码:P.java:package p1;class P {
    public void display() {
    }
    }P1.java:package p1;class P1 extends P {
    public void test() {
    this.display(); // 第1行
    } public static void main(String[] args) {
    P1 p1 = new P1();
    p1.test();
    }
    }(自己的理解:当我们写代码        class P1 extends P {
            }时,编译器会在P1类中保存一个地址,此地址是父类P在内存中的地址,这样,当我们在子类P1中的某个适当的地方用        this.时,就会显示自己本身的类中的成员,以及那个地址指向的父类中的某些成员(指成员属性、成员方法)。当程序执行到第1行语句:        this.display();时,程序就会到P1类中保存的那个地址中找到父类P,然后调用执行父类P中的display()方法。P2、P3、P4、P5类中使用display()方法也是通过这种方式,这5个子类中使用的display()方法都是同一个方法,都是在父类中定义的那个方法。)总结:继承究竟是什么意思?答:拿此例来说,5个子类P1、P2、P3、P4、P5继承了父类P中的display()方法,意思只是说:子类可以调用、使用这个方法而已,并不是继承后就变成自己的了,还依然是父类的,此方法还在父类中。
    可以这样理解“继承”:5个子类P1、P2、P3、P4、P5继承P类,可认为:这5个子类每人用一条箭头指向父类P,这个指向实质是一个内存地址。
    5个子类P1、P2、P3、P4、P5继承父类P中的display()方法,可认为:这5个子类P1、P2、P3、P4、P5每人都用1条箭头指向了父类P中的display()方法,当5个子类要使用此方法时,这5个子类每人就顺着这条箭头去调用执行父类中的那同一个display()方法。
    这时我们再回头看看一位默默无声的人:37楼 joejoe1991
    好,继承的概念我们现在已经清楚了,我们现在再来看“问题1”。
      

  25.   

    好,继承的概念我们现在已经清楚了,我们现在再来看“问题1”。B类继承A类后,A类的私有属性a1究竟有没有继承过来?我们在B类的代码中,        this.出来的列表中找不到a1属性,也就是说:在子类B中访问不了a1属性,那就说明:B类没有将父类的私有属性a1继承过来(注意:继承的意思就是是否能访问、调用。)。有2句话相信许多人听过:----------
    所有的子类都是一个父类,但父类却不是一个子类(父类与子类完全相同的情况除外)。子类都完完整整地包含一个父类。
    ----------
    并且我猜许多人对这2句话没有怀疑过。我也一直没怀疑过,可是,我们在上面得出的结论是:子类B没有继承父类A中的私有属性a1,那不是与“子类都完完整整地包含一个父类。”这句话相违背了吗?答:并不违背。子类确实没有继承父类A中的私有属性a1(注意继承的概念。),但是,谁说子类B就不完完整整包含父类A了,子类B虽然没有继承父类A中的私有属性a1,但是,子类依旧完完整整地包含了一个父类A,也当然包含父类A中的私有属性a1,但是,子类B就是没有继承父类A中的私有属性a1。:)
    我们看0楼的代码,稍微做一些改动:A.java:package p1;public class A {
        private int a1 = 1;
        int a2 = 2;    int getA1() {
            return a1;
        }    int getA2() {
            return a2;
        }    private void getC() {
        }
    }B.java:package p1;public class B extends A {
        public void test() {
         this.fieldA; /** 编译器提示:Multiple ers at this line
          - Syntax error on token ";", invalid AssignmentOperator
          - fieldA cannot be resolved or is not a field
         */
            this.a1;        // 编译器提示:The field A.a1 is not visible(译:A类中的a1属性不可见)
         this.methodA(); // 编译器提示:The method methodA() is undefined for the type B(译:在B类中,methodA()方法未定义)
         this.getC(); // 编译器提示:The method getC() from the type A is not visible(译:A类的getC()方法不可见)
        }    public static void main(String[] args) {
            B b = new B();
            b.test();
        }
    }case 1A:在A类、B类中我们都没有定义fieldA属性,此时在B类的test()方法中访问        this.fieldA;时,编译器提示:Multiple ers at this line
            - fieldA cannot be resolved or is not a field
            - Syntax error on token ";", invalid AssignmentOperatorcase 1B:我们只在A类中定义了私有属性a1,并没有在B类中定义此名称的属性,此时,在B类中的test()方法中访问        this.a1;时,为什么不提示与上面一样类型的错误,而是提示:        The field A.a1 is not visible(译:A类中的a1属性“不可见”)说明什么?答:在B类的代码中竟然能找到只在A类中定义的私有属性a1,说明B类继承A类后,B类中确实已经包含A类的这个私有属性a1了,只是因为对此属性无访问权限(当然也就无法继承),所以提示说:        The field A.a1 is not visible
    case 2A:A类、B类中都没有定义methodA()方法,此时,在B类中的test()方法中访问        this.methodA();时,编译器提示:        The method methodA() is undefined for the type B(译:在B类中,methodA()方法未定义)case 2B:我们只是在A类中定义了私有方法getC(),并没有在B类中定义此名称的方法,此时,在B类中的test()方法中访问        this.getC();时,编译器为什么不提示与上面同样类型的错误,而是提示:        The method getC() from the type A is not visible(译:A类的getC()方法“不可见”)说明什么?答:在B类自己的代码中,竟然能够找到只在A类中定义的那个私有方法getC(),说明B类继承A类后,在B类中确实已经将A类的这个私有方法getC()包括进来了,只是因为没有权限访问(当然也就无法继承),所以,就提示说:        The method getC() from the type A is not visible(译:A类的getC()方法不可见)
    综上证明:对问题1:答:B类继承A类后,B类没有继承A类的私有属性a1,但是,B类却包含了A类的私有属性a1以及整个A类。错误的地方,希望大家指正。
      

  26.   

    想问一下47楼的
    class A{
      public void f1(){
      }
      private void f2(){
      }
    }class B extends A{
      public void f1(){ //为什么这个是覆盖或者重写
      }
      private void f2(){  //这个却是重新定义一个新方法
      }
    }
    如果B中没把A的f1()包含进来 那B中的f1()也是一个新方法 而不是覆盖或者重写(翻译问题?)
    如果B中把A里的f2()包含进来了 那B中不是有2个f2()方法了或者说是我那两个注释有问题? 
      

  27.   

    我认为没有覆盖的情况下,子类是默认调用了super.getA1()。
      

  28.   

    答:回答classnameextendsjava兄弟的问题:你在39楼提供的英文资料讲得很清楚,父类中的private f1(),子类是不能继承的(但:要注意:子类对象中包含有一份完整的父亲对象),而:方法重写的一条重要原则是:子类对象能够继承的方法(由于是对象,故不包含static方法),子类对象才能重写。实际上,从子类对象B的空间来看,B的对象空间中确实含有两个f1()方法(注:不是指方法f1()的程序代码--程序代码都是公用的,而是指向方法 的一个指针),一个包含在它当中的那个父对象中,一个在它自己的扩展的空间中。
      

  29.   

    我的天呐,这样的问题都可以做这么多的testing,真的都是高手,这要是搞个项目,估计十年左右能搞出来了。
      

  30.   

    这里有个问题不知道大家注意到了没有
    我们在编写代码的时候用的第三方IDE
    说明了什么呢,编译前的提示都是IDE说了算的
    此时的IDE能不能看见所有的代码呢,肯定能了,代码都放在那
    如果大家换成命令行来编译(48楼的代码)结果很让你吃惊,编译过后你试着将48楼的代码注释掉前两行
            //this.fieldA;
            //this.a1; 
            this.methodA();
            this.getC();
    结果又不一样
    ----
    我是没想通,更加迷惑了,期待高手
    本来想截图发上来的,结果说我Firefox不支持
      

  31.   

    个人观点:
    这是语义混淆,java的继承和生活中的继承语义不同。
    java的子类中保存父类引用“指针”,通过这个“指针”理论上可以访问父类所有的东西。但是java语言规范里既然规定了子类不能访问父类私有的,所以就要做权限的检查,所有这不是有没有的问题而是可不可以访问的问题。
    这个问题就好像你拿着一个对象,不能因为你不能访问它的私有方法就认为这个对象在给你的时候把私有方法删除了,考虑一下反射体系中的setAccessible(),通过设置权限不就可以访问私有方法了么?说明私有方法还在,只是访问权限改了。
    对子类可不可见,编译前看修饰符起作用,编译后就是访问权限作用了。
    说到底所谓的语言级的继承就是编译期的组合关系+语言规范中的权限规则。
      

  32.   

    第一次看jiangnaisong兄在35楼说的话,看得很糊涂,后来再看这些话,才感到jiangnaisong兄将问题看得很透彻,敬佩!
      

  33.   

    尊敬的版主、管理员:
      您好!  希望您可以不结掉此贴,现在我在上学,时间很紧,这个问题还没有讨论完,还想继续讨论,希望能为后学留下一张比较究竟的帖子,将不胜感激。
    此致
      敬礼
                                              CSDN成员:Drop1                                          2008年5月18日
      

  34.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【Drop1】截止到2008-07-22 13:53:06的历史汇总数据(不包括此帖):
    发帖的总数量:5                        发帖的总分数:80                       每贴平均分数:16                       
    回帖的总数量:5                        得分贴总数量:0                        回帖的得分率:0%                       
    结贴的总数量:3                        结贴的总分数:60                       
    无满意结贴数:0                        无满意结贴分:0                        
    未结的帖子数:2                        未结的总分数:20                       
    结贴的百分比:60.00 %               结分的百分比:75.00 %                  
    无满意结贴率:0.00  %               无满意结分率:0.00  %                  
    楼主加油
      

  35.   

    这问题还真有点意思。有两点是确定的:
      “子类是一个完完整整的父类”(继承正是is-a关系),也就是说子类实例包含了一个完整的父类实例,当然包含了私有的属性/方法
      “子类不能访问父类的私有属性和方法”,也就是说由于封装特性,正如33楼所说,子类对父类的私有属性和方法只有“所有权”没有使用权。
      

  36.   

    /**
     * 测试继承时一个类中能否继承父类的私有属性
     */
    package com.test;class TE {
        private int c = 5;
        int d = 10;
        public void set(int c) {
            this.c = c;
        }
        public int get() {
            return c;
        }
    }
    public class TestExtends extends TE {    public static void main(String[] args) {
            TestExtends te = new TestExtends();
            System.out.println(te.d);
            te.set(20);
            /* System.out.println(te.c); Cannot get 说明不能直接使用继承自父类的私有属性
             * 但是父类的私有属性在子类中确实存在,否则怎么能在子类中给没有的属性赋值呢?
             */ 
            System.out.println(te.get()); // print 20
            // 打印出父类自己的私有属性c值瞧瞧
            TE t = new TE();
            System.out.println(t.get()); // print 5
            // 从子类和父类输出的c的值不同更能说明这一点:子类继承了父类的私有属性
        }}
      

  37.   

    我看很多人钻研得太“深”以致于把java原本很清楚明白地告诉你的东西反而给弄成了不确定的了。
    既然告诉你private是私有的,不能被子类继承,何来“被子类继承但不可见”的怪异理解?首先我们得了解子类对象的实例化过程,子类对象在实例化的过程中会一直上溯到Object。
    我们在定义子类时只定义了与上一级父类差异的部分,但系统怎么知道这个新定义的子类 还有哪些从上一级父类、上上一级父类...继承得来的部分呢?
    这个上溯过程解决了这个问题,在这个上溯过程中,被父类定义为private或被子类重写的都不会被子类继承,即它们很明确地不是子类的组成部分。但这不等于说“不是子类的组成部分就不能被子类采用某种方法取得其值”,这是2回事。
    因为只要某类提供了类似于getter的public方法,任何类都可以取得其private属性的值,与是否父子类毫无关系。对子类实例化时的内存布局应该有个正确的理解,否则往往会误入歧途,把原本正确的当成错误的了。over
      

  38.   


     20楼说的比较好,听君一席话,胜读几天书. 我胡乱总结一下啊,呵呵:
     
     (鸡蛋黄--父类的没有被继承的属性和方法),(鸡蛋清--父类中被继承的属性和方法),(鸡蛋皮--子类) 母鸡生鸡蛋的时候,是先有鸡蛋黄和鸡蛋清,在此基础上创造鸡蛋皮. (呵呵,姑且这么认为吧) 子类(鸡蛋皮)能访问从父类继承到的属性和方法(鸡蛋清),因为它们靠的近. 子类(鸡蛋皮)不能访问那些"父类中没有被子类继承的属性和方法(鸡蛋黄)",因为它们中间隔了个鸡蛋清. 但是,子类(鸡蛋皮)可以通过继承类的方法(鸡蛋清)访问"父类的没有被继承的属性和方法"(鸡蛋黄). 呵呵,类也就是一个数据结构,内存里到底是怎么存储它的,现在还不明白,现在也就这么认为吧. (----------------------csdn 回复2 hehe---------------------)
      

  39.   


    楼主的理解好有问题所谓组合,知道什么是组合吗?
    是一个类中的某一属性为另一个类的实例,如:publice class A{
       private int a;
    .....
    }publice class B{
      private A a;
    ......
    }你说B类能不能用到A类私有变量及私有方法?
      

  40.   

     int a2 = 2;
     不是私有的。共有的。
      

  41.   

    其实早在7楼已经把问题讲的很明白了,78楼把话说的更透彻了,这跟继承有什么关系,你的例子里的getter,setter方法其实只要在包内任何类都能访问的到
      

  42.   

    哗,好热闹啊。。
    我也来发表一下意见:
    看楼主的所有。其实楼主主要是想表述一个问题:getA1() 这个方法被继承后.这个子类是已经"拥有这个方法"(相当于方法复制一份).还是只是调用父类的geta1()方法.如果是前者的话。明显不合理。所以,我认为。楼主的理解有错误。private 属性是不能被继承的。只调用父类的方法。
      

  43.   

    jiangnaisong 的概念很清楚,赞一个。继承是类和类之间定义的关系,类是对象的模板,子类的对象同时是合法的父类对象,所以必须包含父类所有的属性和方法。当然也就包含父类上定义的私有属性。子类的一个对象其实是一组对象。单纯在类和类的关系上讲私有特性不能继承,概念上没错。
    具体运行的时候,子类对象掌握的内存空间中会嵌套包含有父类中定义的私有变量,这本来就是一眼就能看穿的结果。对jiangnaisong“洋葱”的比喻方式再赞一个。
      

  44.   

    看不见的并不代表不存在,不能访问的并不代表没有继承,其实构造方法也被继承了,至少你可以调用super()。子类继承了父类的一切,所有的东西。
      

  45.   

    很简单嘛!!!!!  a1如果真的被继承下来的话    那你在B类中重新定义一个子类自己的非私有的方法void test(){return al;}  然后再调用这个方法进行测试       如果能够输出结果说明继承了不可见
    如果报错则 7楼是对的