[Java] 8.3. 保護化

protected,只予許在繼承的情況下才可被存取的成員(建構式、屬性與方法)。

 

image/svg+xml8.3. 保護化 - protected package personMgt ; public class Person { public Person(){} public String id; public String name; public String gender int age ; public int getAge (){ if ( gender==" 女⽣ " ) return 18 ; else return age ; } public void setAge ( int age){ this .age=age; } // 略過⼀些程式 } package personMgt.companyMgt ; import personMgt.*; public class Employee extends Person{ public String empID; public int salary; public Employee(){ super (); } int getRealAge (){ return age ; } } package personMgt ; public class Person { public Person(){} public String id; public String name; public String gender; protected int age ; public int getAge(){ if (gender== " 女⽣ " ) return 18 ; else return age; } // 略過⼀些程式 } package personMgt.companyMgt ; import personMgt.*; public class Employee extends Person{ public String empID; public int salary; public Employee(){ super (); } int getRealAge (){ return age ; } } package personMgt ; public class Person { public Person(){} public String id; public String name; public String gender; protected int age; public int getAge(){ if (gender== " 女⽣ " ) return 18 ; else return age; } public void setAge( int age){ this .age=age; } public void show (){ System.out.println(id); System.out.println(name); System.out.println(gender); System.out.println(getAge()); } } package person M gt.company M gt; import personMgt.*; public class Employee extends Person { public String empID; public int salary; public Employee(){ super (); } int getRealAge(){ return age; } void show (){ System.out.println(id); System.out.println(name); System.out.println(gender); System.out.println(getAge()); System.out.println(empID ); System.out.println(salary); } } 編譯時發⽣錯誤 Employee.java:15: error: show() in Employee cannot override show() in Person void show(){ ^ attempting to assign weaker access privileges; was public 1 error 對於類別⽽⾔,只可使⽤⼀種存取修飾詞來修飾類別的存取權限,那就是 public 。換句話說,在套 件的情況下,對類別⽽⾔只有公開化存取與不公開化存取的兩個情況。 當類別定義為公開化時,使⽤ protected public ⽤來修飾建構式、屬性與⽅法等的修飾詞才會產 ⽣效⽤。因為 protected public 在不同的套件下,將會對各建構式、屬性與⽅法產⽣不同的影 響。下表為存取修飾詞與套件相關的存取權限表, V 表⽰可以存取相關的建構式、屬性與⽅法,⽽ X ⽰不可存取。 存取修飾詞 可⽤來修飾類別 private X (default) V protected X public V 存取修飾詞 相同套件 不同套件 private X X (default) V X protected V 繼承下充許存取 public V V J8_3_1 – Person.java 1. ⼈員類別( Person )位於⼈員管理套件下( personMgt )。 J8_3_1 – Employee.java 1. ⼈員類別( Person )位於⼈員管理套件下( personMgt )。 2. 注意,年齡屬性( age )是我們唯⼀沒有使⽤ public 進⾏公開化的屬性。 3. 雖然透過 getAge() 可取得年齡,但 若是女性的話,其年齡將會永遠是 18 的情況,因此無法正確得知真實年齡。 6. 在不同的套件下,是無法存取年齡屬性的, 因為年齡屬性沒有使⽤ public 進⾏公開化。即 便是繼承的員⼯類別( Employee )也是⼀樣。 若這時老闆想問員⼯真實的年齡呢?那不就無法 告訴老闆真實的年齡了?! 4. ⽽員⼯類別( Employee )位於公司管理套件 companyMgt )中,因此會受到套件之間的存取限制。 5. 這是取得真實年齡⽅法( getRealAge() ),意圖取得⼈員的真實年齡。 J8_3_2 – Person.java J8_3_2 – Employee.java 2. 在此使⽤ protected 關鍵字,將年齡屬性( age )進⾏保護化的動作。 3. 員⼯類別( Employee )位於公司管理套件 companyMgt )中,因此會受到套件之間的存取限制。 . 這是取得真實年齡⽅法( getRealAge() ), 意圖取得⼈員的真實年齡。 5. 因為有繼承的關係存在,因此可以繼承⼈ 員類別的保護化後的年齡屬性,並存取到年齡 屬性的真實年齡,這就是 protected 的功能。 如此,當老闆問員⼯真實的年齡時,即可透過 取得真實年齡⽅法告訴老闆真實的年齡。 當然,類別上的建構式與⽅法也是可以透過 protected 進⾏套件外繼承存取的 限制開放。 J8_3_3 – Person.java private default protected public 存取權限 2. ⼈員類別( Person )位於⼈員管理套件下( personMgt )。 1. 這是 Java 的所有存取權限,由⼤⾄⼩排列為 public protected (default) private ,在此 “(default)” 即表⽰不使⽤任何存取權限的情況下, 即預設為 “(default)” 。當越⼤的權限表⽰越開放。 3. ⾃我介紹⽅法( show() )是⼀個以最⼤(即最開放)的權限- public 進⾏公開化。 4. 這是員⼯類別( Employee ), 其繼承⾃⼈員類別。 5. 若這時要改寫繼承⼈員類別的⾃我介紹⽅法( show() ),但卻改變了存取 的權限,將存取權限的範圍變⼩為預設權限- default (即不寫任何存取修飾 詞)。這時會發⽣編譯失敗,告訴您不可以更弱(即更⼩)的權限來進⾏改 寫。在物件導向的理論中,繼承即產⽣ ”IS-A” 的關係,因此不可縮⼩存取權 限,這導致了⼦類別無法轉型成⽗類別進⾏統⼀的操作,因為以更⼩的存取權 限改寫即有⽅法,將造成⽗類別的⽅法被⼦類別隱藏起來了,這是不合理的。 在不同的套件情況下, 可以為繼承的員⼯透露實際的年齡嗎? 老闆還是要知道員⼯的實際年齡的 protected 以繼承的⽅式存取⼈員類別的年齡屬性 注意,改寫⽅法時⽅法存取的權限只可更⼤,但不可變⼩ J8_3_3 – Employee.java 1 1 套件與存取權限總整理

留言