作者jackblack ()
看板java
标题Re: [问题] 关於向上转型
时间Sun Oct 9 02:07:43 2016
※ 引述《DisdainU (茎茎濡吮汁)》之铭言:
: class Derived extends PrivateOverride{}
: public class PrivateOverride{
: private void f(){
: System.out.println("private f()");
: }
: public static void main(String[] args){
: PrivateOverride p=new Derived();
: p.f();
: }
: }
: /* output:
: private f()
: */
: 想问的是 既然base class的f()是private
: 也就代表在Derived中看不到f()
: 那为什麽例子中却可以执行出结果?
: 手机排版 请见谅
: -----
: Sent from JPTT on my Sony D6653.
Java 操作物件时是以宣告型别为主
并且在建立物件实体时会先建立父类别们的实体(一路到 Object 类别)
因此以 PrivateOverride 宣告的物件 p
虽然实际上为 Derived 的实体
但型别仍被视为 PrivateOverride
另外存取修饰字的限定对象是「型别」
private 在同个型别内都是可以叫用的
不论是由同类别的其它方法呼叫:
privateMethod()(等同於 this.privateMethod())
或
privateStaticMethod()(等同於 ClassName.privateStaticMethod())
还是由此类别的物件实体呼叫:
obj.privateMethod()
或
obj.privateStaticMethod()
你的 main 方法放在 PrivateOverride 类别中
又是以 PrivateOverride 宣告并建立 Derived 的物件实体
所以同时满足了宣告型别与存取限制的两个条件
因此你的 f() 可以成功呼叫
若是把 main 方法改放到 Derived 中就会因为存取限制而无法呼叫了
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 122.116.240.120
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1475950066.A.A65.html
1F:推 v9290026: 推! 10/09 02:19
2F:推 DisdainU: 意思是说,如果我在Derived中加入同样的f(),但将此meth 10/09 02:47
3F:→ DisdainU: od改成public(意味两个f()为不一样的method只是名字一 10/09 02:47
4F:→ DisdainU: 样),其余不变,执行结果依然是呼叫private method,是 10/09 02:47
5F:→ DisdainU: 因为java在操作物件是先以reference的型别为主。我这样 10/09 02:47
6F:→ DisdainU: 理解有误吗? 10/09 02:47
首先
是否为同个方式是依据「方法签名」
方法签名就是 methodName 以及方法参数的型别、数量与顺序
方法签名相同就会被视为同个方法
不过对 Derived 型别来说
PrivateOverride 的 f() 是不可见的(无法存取)
所以你在 Derived 加入的 f() 虽然方法签名和 PrivateOverride 的 f() 一样
仍然被视为不同的方法
7F:推 haha02: 应该是因为private method无法被override 两者视为不同的m 10/09 03:42
8F:→ haha02: ethod吧 10/09 03:42
9F:推 haha02: 你到Derived#f()上加@Override看编译会不会报错就知道了 10/09 03:46
10F:→ haha02: 如果会表示没有override到 10/09 03:46
可以看看以下范例:
class ChildClass extends FatherClass {
public void mehtod() {
System.out.println("it's ChildClass");
}
}
public class FatherClass {
private void mehtod() {
System.out.println("it's FatherClass");
}
public static void main(String[] args) {
FatherClass objDeclaredByFather = new ChildClass();
objDefinedByFather.mehtod();
// 印出「it's FatherClass」
ChildClass objDeclaredByChild = new ChildClass();
objDefinedByChild.mehtod();
// 印出「it's ChildClass」
}
}
操作物件时会以宣告的型别来寻找定义方法
如果子类别物件实体有「相同」的方法(Override 父类别)
那就执行子类别版本
如果子类别物件实体中没有相同的方法就往上层(父类别们的实体)找
这个例子中
objDeclaredByFather 呼叫的是 FatherClass 所定义的 mehtod()
objDeclaredByChild 呼叫的则是 ChildClass 定义的 mehtod()
因为 FatherClass 定义的 mehtod() 和 ChildClass 定义的 mehtod() 是不同的方法
※ 编辑: jackblack (122.116.240.120), 10/09/2016 10:00:01
11F:推 DisdainU: 了解了!谢谢解答 10/09 12:52
12F:推 v9290026: 加@override就会很清楚了 10/09 17:26