第二章:簡單 Java 程式解析
第三章:變數與資料型態
第四章:運算子、運算式與敘述
第五章:選擇性敘述與迴圈
第十章:實例變數與函數、類別變數與函數

類別成員中的公有與私有

public & private

為了保護資料成員不被任意的修改,在此篇將會談論到透過一個公有私有的機制,來防範這個漏洞。

因此先從私有資料成員開始談論起。

本章練習的範例來舉例:

class Circle{ //定義類別Circle
double pi=3.14;
double radius;
void show_area()
{
System.out.println("面積= "+pi*radius*radius);
}
}
public class ch08_3 {
public static void main(String[] args) {
Circle moon=new Circle(); //建立 moon 物件
moon.pi=3.1415;
moon.show_area();
}
}

在資料成員的部分,我們有 pi與 radius; 因為這是一個計算圓面積的程式,在主程式設值給資料成員 radius 聽起來很正常; 雖然主程式並無設值給 pi,但 pi 很有可能因為程式的規模一大,而導致值會有所變更; 同理, radius 也有可能在此時設值為 2 ,但又可能遭到修改。

為了防範此類事情發生,有了 公有與私有 ( public & private) 的機制。

私有

class Circle{ //定義類別Circle
private double pi=3.14;
private double radius;
.....
}

直接在宣告最前方,個別加上 private ,如此一來將無法從類別以外的地方 設定或直接讀取。 進而達到保護的效果。

class Circle{ //定義類別Circle
private double pi=3.14;
private double radius;
void show_area()
{
System.out.println("面積= "+pi*radius*radius);
}
}

在類別函數成員的部分,是可以正常讀取到私有成員 pi 與 radius 的。

public static void main(String[] args) {
Circle moon=new Circle(); //建立 moon 物件
moon.radius=-3;
moon.show_area();
}

但在主程式的部分,就無法設值給 radius 了。

公有

既然有 私有 private 就有 公有 public

剛剛的程式碼,設定 private 之後,也無法設值計算圓面積,那到底保護了資料成員又有何作用? 將上述的程式做一個修改,成一個較完善的程式,就會慢慢清楚囉~:

class Circle{ //定義類別Circle
private double pi=3.14;
private double radius;
// 設定資料成員為私有
private double area()
{ //設定計算面積的函數為私有
return pi*radius*radius;
}
public void show_area()
{ //設定列印面積的函數為公有
System.out.println("area="+ area());
}
public void setRadius(double r)
{ //設定一個設定半徑的函數為公有
if (r>0)
{
radius=r;
System.out.println("radius= "+radius);
}
else System.out.println("半徑輸入錯誤");
}
}
public class ch08_3 {
public static void main(String[] args) {
Circle moon=new Circle(); //建立 moon 物件
moon.setRadius(3);
moon.show_area();
}
}

以下來一步步講解:

首先是類別的部分,設為私有的除了資料成員外,也設定函數成員area 為私有

private double pi=3.14;
private double radius;
// 設定資料成員為私有
private double area()
{ //設定計算面積的函數為私有
return pi*radius*radius;
}

可以注意到,area 函數 單純為一個計算值的函數。

再來看到設定公有的函數:

分別有 呼叫列印面積的函數

public void show_area()
{ //設定列印面積的函數為公有
System.out.println("area="+ area());
}

以及設定半徑的函數

public void setRadius(double r)
{ //設定一個設定半徑的函數為公有
if (r > 0)
{
radius=r;
System.out.println("radius= "+radius);
}
else System.out.println("半徑輸入錯誤");
}

主程式方面,由於無法呼叫私有的函數或直接設值給私有資料成員; 因此在此是呼叫公有函數

public static void main(String[] args) {
Circle moon=new Circle(); //建立 moon 物件
moon.setRadius(3);
moon.show_area();
}

這樣有什麼好處呢?除了可以判斷輸入的值是否正確之外,還可以有效保護資料成員不被程式任意的更改。

呼叫設值函數時:會傳進 if else 做判斷,若半徑大於零 就設定 剛剛傳進的值 r 給 radius; 若設定的值小於零,那麼就直接印出輸入錯誤的訊息

moon.setRadius(3);

注意

初次學程式雖然都是寫單一的小程式練習; 但日後一定會有大型的專案撰寫,除了學習相關的觀念,同時也是替日後打下強大的基礎。

本章的 公有與私有 ( public & private) 除了上述示範是在同一支程式底下運作外,在此也要給一個觀念:

  1. 若冠上 public 公有的成員,可以被 其他程式自由的存取

  2. 若冠上 private 私有的成員,除了 package 其他程式無法存取外,自身的程式也無法存取;運作的範圍只在該類別當中

  3. 若省略 公有與私有 ( public & private) 都不使用,那麼成員只會在同一 package 存取使用