為了要防止 class 內部的變數遭到不正常操作
我們可以將變數設為 private 再提供 public method 存取
C# 特別為了上述狀況打造了 Get & Set 存取器
讓程式碼能夠更為簡潔整齊
教學影片
注意:影片有高畫質 720P 的選項,可以看得更清楚喔!
重點提示
1. Get & Set 存取器的語法如下:
......... // 宣告變數(通常是 public)
{
get { .... } // 希望變數讀取時執行的程式碼
set { .... } // 希望數值存入時執行的程式碼
}
2. 如果只使用 get 而去除 set 的話,該變數將會變為唯讀
3. 使用 Get & Set 存取器時,並不一定要有對應的 private 變數
4. Get & Set 存取器可以用來即時運算一些平常大家認為是變數的數值,像是 Money
練習
你現在是一位遊戲公司的設計師,這次受命完成玩家類別的部分程式碼
其中必須要完成以下兩項工作:
1. 撰寫計算玩家身上物品總值(TotalValue) 的程式碼
2. 撰寫讓外部物件存取飢餓度(HungerRate) 的程式碼
注意:飢餓度必須介於 0~100 之間,所以要想辦法防止外人存取時超出範圍
以下是玩家的部分程式碼,請完成 TODO 的部分:
class Player {
private int countGold; // 擁有的金子數目,每個金子值 50
private int countSilver; // 擁有的銀子數目,每個銀子值 25
private int countCopper; // 擁有的銅的數目,每個銅值 10
// TODO: 欠缺計算總值的程式碼
private int hungerRate; // 飢餓度,必須介於 0~100 之間
// TODO: 欠缺存取飢餓度(hungerRate) 的程式碼
public Player() {
this.countGold = 0;
this.countSilver = 0;
this.countCopper = 0;
this.hungerRate = 80;
}
public void pickAGold() {
countGold++;
}
public void pickASilver() {
countSilver++;
}
public void pickACopper() {
countCopper++;
}
}
當你完成後,請建立一個 Windows Form 專案並加入一個新的 Player class 檔案
將剛剛撰寫的程式碼替換掉 player.cs 中 class 的程式碼
另外在視窗放置一個簡單的按鈕
將下列的測試用程式碼貼上:
private void button1_Click(object sender, EventArgs e) {
Player player = new Player();
player.pickAGold();
player.HungerRate += 10; // 餓了,飢餓度上升
player.pickASilver();
player.HungerRate += 10; // 餓了,飢餓度上升
player.pickASilver();
player.HungerRate += 10; // 餓了,飢餓度上升
MessageBox.Show("飢餓度:" + player.HungerRate + ",身上物品總值:" + player.TotalValue);
player.pickACopper();
player.HungerRate -= 60; // 吃了一個可以減少 60 飢餓度的東西
player.pickAGold();
player.HungerRate -= 60; // 吃了一個可以減少 60 飢餓度的東西
MessageBox.Show("飢餓度:" + player.HungerRate + ",身上物品總值:" + player.TotalValue);
}
理論上當你按下按鈕執行後,應該要得到兩個對話框如下:如果你的結果一模一樣,那就表示你成功囉!
相關資訊連結
微軟官方(MSDN) 對於 get 的介紹
http://msdn.microsoft.com/zh-tw/library/ms228503.aspx
微軟官方(MSDN) 對於 set 的介紹
http://msdn.microsoft.com/zh-tw/library/ms228368.aspx
大哥 說實在的我沒有成功 有沒有正解阿!
回覆刪除當然有正解囉~
刪除之後我可能會找一天整理所有問題的解答
在這之前就請你多想想看囉
public int HungerRate
回覆刪除{
get { return hungerRate; }
set {
if (value >= 100)
hungerRate = 100;
else if (value <= 0)
hungerRate = 0;
else
hungerRate = value;
}
}
執行成功!不過對於TotalValue的結果不太能理解耶...為什麼是100跟160呢?可以請小山老師講解一下嗎^^?
回覆刪除因為在執行的程式碼中
刪除第一次顯示之前,玩家一共撿了 1 個金子跟 2 個銀子
家裡來總共為 100 (50 + 25 * 2)
到第二次顯示之前,玩家又撿了 1 個金子跟 1 個銅
這個時候別忘記之前身上就已經有 100 了
所以再增加 60 (50 + 10) 之後
就變成 160 了
請問這樣有回答道你的問題嗎?
瞭解囉!謝謝小山老師的詳細解說~
刪除小山老師 我這邊的TotalValue 不知道為甚麼根您的結果不太一樣 我的是120跟170 不懂為甚麼 我在邊附上我打的程式碼
刪除Player player = new Player();
player.pickAGold();
player.HungerRate += 10; // 餓了,飢餓度上升
player.pickASilver();
player.HungerRate += 10; // 餓了,飢餓度上升
player.pickASilver();
player.HungerRate += 10; // 餓了,飢餓度上升
MessageBox.Show("飢餓度:" + player.HungerRate + ",身上物品總值:" + player.TotalValue);
player.pickACopper();
player.HungerRate -= 60; // 吃了一個可以減少 60 飢餓度的東西
player.pickAGold();
player.HungerRate -= 60; // 吃了一個可以減少 60 飢餓度的東西
MessageBox.Show("飢餓度:" + player.HungerRate + ",身上物品總值:" + player.TotalValue);
internal class User// 使用者名稱 以及使用者密碼
{
private string Username;//名稱
private string Password;//密碼
private int hP;//血量
private int count1, count5, count10; //硬幣
public int Money // 統計自己有多少錢 只有get 代表指能讀取 不能存入
{
get
{
return count1+ count5*5+count10*10;
}
}
public int HP
{
get { return hP; } // 在讀取HP時 會自動呼叫 //如果只留下get 讀取 那麼該變數 就會變成唯讀只能讀取 不能存
set // 存入數值時會自動呼叫
{
if (value < 0) // 這邊的value就代表存入的值 例如:uesr.HP = 10 這邊的10就是value 10<0 不成立 所以 hp= value hp就等於10
hP = 0;
else
hP=value;
}
}
public User(string username, string password)//建構子 使用者的物件 建構子
{
this.Username = username;
this.Password = password;
this.hP = 100; //設定一開始的血量所有同類的物件 都是100
count1 = 1; // 1塊硬幣有1個
count5 = 5;//5塊硬幣有5個
count10 = 10;//10塊硬幣有10個
}
public void hurt(int decreaseHP) // decrease 減少的意思 hurt 受傷的意思
{
if (hP >= decreaseHP)
hP -= decreaseHP;
else
hP = 0;
}
public int getHP() // 讀取 血量
{
return hP;
}
public bool Comparepassword(string targetpassword) //Comparepassword 比較密碼 targetpassword 目標密碼
{
if (this.Password == targetpassword)
{
return true;
}
else
{
return false;
}
}
public string getusername()//呼叫 使用 名稱
{
return Username;
}
}
不好意思 打擾了 我找到答案了 我的public int TotalValue 這個屬性裡面的統計金額的 寫成兩個countCopper
刪除小山老師您好,想請問以下寫法是否妥適,在寫的途中發現只要在button按鈕事件中沒有先assign TotalValue值的話,set 是不是不會有作用,所以這題總資產要在 get裡面先寫好,又或者是在外面先寫好method之後在get裡面呼叫,這樣的想法是正確的嗎?
回覆刪除private int totalvalue;
public int TotalValue
{
get
{
totalvalue = 50 * this.countGold + 25 * this.countSliver + 10 * this.countCopper;
return totalvalue;
}
}
恩,這樣想法是對的
刪除這題就是要求你用 get 存取器來完成 TotalValue
因此當你呼叫 TotalValue 時,他都會即時計算總金額為多少
小山老師
回覆刪除我想請教一下所謂的"自動屬性實作"
程式碼如下
class Student
{
public string StuID{ get; set; }
public string StuName{ grt; Srt; }
}
這段程式碼是何意義呢??
我搞不太懂它的用途@@
請小山老師解惑
12萬分感謝!!!
作者已經移除這則留言。
回覆刪除大家好,我在寫練習題那邊HungerRate那個method的時候一直寫不出來,到網路上查資料之後才突然想到解決答案
回覆刪除我不直接顯示以免大家直接看到就不能自己寫了,但是如果真的沒有頭緒可以看一下!(我放下面一點以免你們不小心看到)
可以在HungerRate的method的get&set那邊的set裡面先打(private的變數)hungerRate = value
之後再用一個if與一個else if來限制答案不要超過100並且不要小於0!!
終於成功了!! 原本卡在value概念不清楚,出錯時才發現對value是錯的(把value當作加數....)
回覆刪除public int TotalValue
回覆刪除{
get { return countCopper * 10 + countSilver * 25 + countGold * 50; }
}
public int HungerRate
{
get { return hungerRate; }
set
{
if (value > 100)
hungerRate = 100;
else if (value <= 0)
hungerRate = 0;
else
hungerRate = value;
}
}
久違的交作業
一開始不知道if else if else的用法
在做HungerRate時一直在想怎樣設定飢餓度在0~100之間
後來看了留言之後才恍然大悟
private void button9_Click(object sender, EventArgs e)
回覆刪除{
Player player = new Player();
player.pickAGold();
player.HungerRate += 10; // 餓了,飢餓度上升
player.pickASilver();
player.HungerRate += 10; // 餓了,飢餓度上升
player.pickASilver();
player.HungerRate += 10; // 餓了,飢餓度上升
MessageBox.Show("飢餓度:" + player.HungerRate + ",身上物品總值:" + player.TotalValue);
player.pickACopper();
player.HungerRate -= 60; // 吃了一個可以減少 60 飢餓度的東西
player.pickAGold();
player.HungerRate -= 60; // 吃了一個可以減少 60 飢餓度的東西
MessageBox.Show("飢餓度:" + player.HungerRate + ",身上物品總值:" + player.TotalValue);
}
請問小山老師 為甚麼我出來的結果 根您的不太一樣 飢餓度對了 可是總值 第一次顯示是120 第二次顯示是170 到底哪裡有問題呢
internal class Player
{
private int countGold; // 擁有的金子數目,每個金子值 50
private int countSilver; // 擁有的銀子數目,每個銀子值 25
private int countCopper; // 擁有的銅的數目,每個銅值 10
private int hungerRate; // 飢餓度,必須介於 0~100 之間
// TODO: 欠缺計算總值的程式碼
public int HungerRate //存入或讀取 飢餓度的屬性 // TODO: 欠缺存取飢餓度(hungerRate) 的程式碼
{
get { return hungerRate; }
set
{
if (value < 0)
hungerRate = 0;
else if (value>=100)
hungerRate = 100;
else
hungerRate = value;
}
}
public int TotalValue
{
get
{
return countGold * 50 + countSilver * 25 + countSilver * 10;
}
}
public Player()
{
this.countGold = 0;
this.countSilver = 0;
this.countCopper = 0;
this.hungerRate = 80;//飢餓度80
}
public void pickAGold()
{
countGold++;
}
public void pickASilver()
{
countSilver++;
}
public void pickACopper()
{
countCopper++;
}
}
兄弟,你在這段return countGold * 50 + countSilver * 25 + countSilver * 10;
刪除寫了兩個銀塊,最後一個是 countCopper * 10; 才對哦