作者sbrhsieh (十年一梦)
看板java
标题Re: [问题] 在子类别new建构子为protected的父类别
时间Sun May 11 02:37:54 2014
※ 引述《pzyc79 (I'm bored)》之铭言:
: 标题: [问题] 在子类别new建构子为protected的父类别
: 时间: Sun May 11 00:53:48 2014
:
: ===============Class Test:===============
: package a;
:
: public class Test {
: protected Test(){
: }
: }
:
: ===============Class Test2:==============
: package b;
:
: import a.Test;
:
: public class Test2 extends Test{
: void fun(){
: Test t = new Test(); //Test() is not visible
: }
: }
:
: WHY? 宣告protected不是可以在子类别中看见吗?
我觉得这一篇的问题同
#1J5-rnUZ [问题] Object的clone()问题。
就是误解了 protected member 可被不同 package 的 subtype 存取的意义。
先把你的 sample code 稍微改成这样:
// a/Test.java
package a;
public class Test {
protected Test() {
System.out.println("Test::Test()");
}
}
// b/Test2.java
package b;
import a.Test;
public class Test2 extends Test {
public static void main(String[] args) {
new Test2();
}
}
编译没问题啊,那麽 Test2 的确可以"看的见" Test 的 protected constructor 呀,
不然编译器帮你添加的 public Test2::Test2() constructor 怎麽可以 invoke
Test::Test() constructor?(跑跑看 b.Test2 验证一下)
:
: --
:
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.240.30.17
: ※ 文章网址: http://webptt.com/cn.aspx?n=bbs/java/M.1399740834.A.2E7.html
: ※ 编辑: pzyc79 (111.240.30.17), 05/11/2014 00:56:05
: 推 luoqr:是在 new Test2() 时 super() 看的见, 不是在new Test()看见 05/11 01:00
:
: ===============Class Test:===============
: package a;
:
: public class Test {
: Test(){
: }
: }
:
: ===============Class Test2:==============
: package a;
:
: import a.Test;
:
: public class Test2 extends Test{
: void fun(){
: Test t = new Test(); //OK
: }
: }
:
: 照你说的「是在new Test2()时super()看的见 ,不是在 new Test() 看见 那换成这样…… 在new Test()又看的见了?
: ※ 编辑: pzyc79 (111.240.30.17), 05/11/2014 01:33:01
这个例子完全被 package default 的规则所涵盖了,我不知道举这样的例子是
强调什麽?
根据 protected 的规则(扣掉 package default 相关的部份):
Test2 object 只能碰自己承袭而来的那份由 Test 所定义的 subobject 的 protected
member。
什麽意思呢?
把 Test/Test2 再稍微修成:
// Test.java
package a;
public class Test {
protected Test() {
System.out.println("Test::Test()");
}
public Test(String notImportant) {
System.out.println("Test::Test(String)");
}
protected void foo() {
System.out.println("Test::foo()");
}
}
// Test2.java
package b;
import a.Test;
public class Test2 extends Test {
public static void main(String[] args) {
new Test2().bar();
}
public void bar() {
System.out.println("<Test2::bar()>");
foo(); // 同 this.foo();
System.out.println("</Test2::bar()>");
}
}
这没有问题,Test2 object 还是可以要求他自己(或体内的那份 Test subobject,
看你喜欢怎麽去看这回事)去执行 foo 操作。protected 修饰词加在 constructor/
non-constructor 的意义无不同(回你在他帖中的推文)。
但是他不能要求别的 Test object 去执行 foo 操作。替 Test2 加上
public void fooBar(String s) {
System.out.println("<Test2::foobar(String)>");
new Test(s).foo();
System.out.println("</Test2::foobar(String)>");
}
是行不通的,因为 protected 赋予的就不是这麽宽。
如果要我类比的话(不过通常我举得类比例子不多人看得懂),就像是你是你老爹的
儿子,故你可以去要求你爹的遗产,不管你有没有跟你爹住在一起,或是跟你爹姓,
你不能够去要求碰他人的老爹的遗产。
而 package default 的话则是只要住在同一个屋檐下,那你就可以偷同屋檐下
任一个人的钱,不管你称不称他为爹。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.172.239.93
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/java/M.1399747077.A.181.html
※ 编辑: sbrhsieh (1.172.239.93), 05/11/2014 02:45:16
1F:推 gmoz:推 05/11 09:29
2F:推 pc2990:太强了 这篇是正解.. 05/15 21:20