2014-09-13 52 views
2

我認爲我瞭解protected修飾符,但看起來好像我沒有。 的例子很簡單:來自其他包的受保護的方法調用

package com; 
public class Main { 

    protected void method1() { 
     // some code 
    } 
} 

和:

package net; 

import com.Main; 

public class Out extends Main { 

    public Out(){ 
     Main m = new Main(); 
     m.method1(); 
    } 
} 

爲什麼我不能叫method1從延伸到Main一類?編譯器錯誤建議將修改器更改爲public

我真的很困惑。

回答

0

,因爲你在創建一個Out例如Main(一OutMain,但Main不是Out)它不工作。

它會工作,如果你直接method1撥打:

public Out(){ 
    method1(); 
} 

,或者如果你有一個Out實例:

public Out(){ 
    Main m = new Main(); 
    ((Out)m).method1(); 
} 

public Out(){ 
    Out m = new Out(); 
    m.method1(); 
} 

Here你可以找到一些詳情(第6.6.2節):

對象的受保護成員或構造函數可以從僅在負責實現該對象的代碼聲明的包中進行訪問。

+0

第一個代碼示例不是一種方法。它在Java中稱爲'constructor'。這很清楚。他可以用我的一個構造函數替換他的構造函數,一切都可以正常工作。 – 2014-09-13 08:46:38

+0

'方法1()'在一個名爲'Out'的類中不是構造函數 – ataulm 2014-09-13 08:47:24

+0

'public Out()'=一個公共構造函數; 'method1()'=方法調用;我認爲一切都很清楚。他可以直接調用'method1',因爲它是從Main繼承的受保護的方法。 – 2014-09-13 08:49:29

0
package com.example.furniture; 

public class Seat { 

    public boolean canAccommodate(int numberOfPeople) { 
     return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate(); 
    } 

    protected int getMaxNumberOfPeopleThatICanAccommodate() { 
     return 4; 
    } 

} 


package com.example.furniture; 

public class Chair extends Seat { 

    public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) { 
     return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate(); 
    } 

} 

以上會即使getMaxNumberOfPeopleThatICanAccommodate()Chair明確定義的工作,Chair將使用實施從Seat。所述protected修飾符允許子類調用(或覆蓋)的方法,並且還允許類從同一個包調用的方法:

package com.example.furniture; 

public class Bed { 

    public boolean canFitMorePeopleThanThis(Seat seat) { 
     return peopleICanFit() > seat.getMaxNumberOfPeopleThatICanAccommodate(); 
    } 

    private int peopleICanFit() { 
     return 2; 
    } 

} 

並且延伸至與受保護的方法中的一個類可以覆蓋該方法太:

package com.example.furniture; 

public class ReallySmallChair extends Seat { 

    public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) { 
     return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate(); 
    } 

    @Override 
    protected int getMaxNumberOfPeopleThatICanAccommodate() { 
     return 1; 
    } 

} 

但是如果你試圖從外部包訪問受保護的方法,它不會工作:

package com.example.room; 

public class LivingRoom { 

    Seat seat = new Seat(); 
    Seat chair = new Chair(); 

    public boolean canAccommodate(int numberOfPeople) { 
     int maxAccommodate = seat.getMaxNumberOfPeopleThatICanAccommodate() + 
       chair.getMaxNumberOfPeopleThatICanAccommodate(); 

     return numberOfPeople <= maxAccommodate; 
    } 

} 

你會得到一個編譯器嘗試訪問seat.get...chair.get...方法時出錯。

如果您在不同的包中有Seat的子類,那麼您仍然可以訪問受保護的方法,因爲它滿足兩個條件之一(一個子類或同一個包中的另一個類),但只有它自己的方法:

package com.example.room; 

public class RecreationalVehicle extends Seat { 

    public boolean canAccommodate(int numberOfPeople) { 
     return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate();    
    } 

} 

這工作,因爲getMaxNumberOfPeopleThatICanAccommodate()屬於RecreationalVehicle(它的一個子類)的方法。如果試圖從一個Seat變量訪問它,它不會允許它,因爲RecreationalVehicle不允許觸碰另一實例的保護方法,因爲它不是在同一個包:

package com.example.room; 

public class RecreationalVehicle extends Seat { 

    Seat seat = new Seat(); 

    public void foo() { 
     seat.getMaxNumberOfPeopleThatICanAccommodate();    
    } 

} 

會導致編譯器錯誤。

0

看起來你實際上可以調用從不同的包超的方法,你都無法做到這一點明確:

package com.example.room; 

import com.example.furniture.Seat; 

public class RecreationalVehicle extends Seat{ 

RecreationalVehicle rec = new RecreationalVehicle(); 

public boolean canAccomodate(int numberOfPeople){ 

    int n = rec.getMaxNumber(); 

    getMaxNumber(); 
    return true; 
    } 
} 

這個類不實現getMaxNumber(),但調用rec.getMaxNumber()是好。 這是對超類的實際調用,對吧?

問題是:爲什麼我們不能在其父類引用類型的對象上調用其他程序包 的超類方法?

+0

這不應該作爲回答發佈,因爲它不是你的問題的答案。在@curiosu的答案最後發佈的引言解釋了 - 只有當它被包含在該包之外的[protected方法]時,_only_才被代碼聲明,該代碼負責實現該對象**。子類負責實現,所以即使子類在另一個包中,它也可以調用超類中的方法。 – ataulm 2014-09-14 17:20:46

+0

在上面的代碼示例中,您甚至可以訪問RecreationalVehicle _field_的_private_成員,因爲您在RV類中,而私有修飾符允許在類中進行訪問。 Seat類不在此範圍內 - RV不能更改或修改Seat類。這有點微妙的區別:/ – ataulm 2014-09-14 17:24:11

相關問題