string myString;
DateTime myTime;
DataTable myTable;
Button myButton;
List<string> myStringList;
public class 水果
{
public int 價格;
public string 滋味;
}
static class Program
{
/// 應用程式的主要進入點。
static void Main()
{
水果 我的蘋果; // 把水果設計圖拿給「我的蘋果」
我的蘋果 = new 水果(); // 依水果設計圖做出「我的蘋果」
我的蘋果.價格 = 1000;
我的蘋果.滋味 = "酸酸甜甜的";
MessageBox.Show($"價格: {我的蘋果.價格}" +
$"\n嗯~吃起來: {我的蘋果.滋味}");
// 對話框裡顯示 價格:1000 嗯~吃起來:酸酸甜甜的
}
}
TIP: 新手容易出錯的指派運算子 以及 new 運算子
指派運算子 (=) 有一個很好理解又很容易被忘記的特性:指派 (等號右邊) 的物件和被指派 (等號左邊) 的物件兩者類別通常皆須一致。上面程式碼第六行:
我的蘋果 = new 水果();
- 指派運算子左邊的「我的蘋果」是一水果物件,其值為空。
- 指派運算子左邊的「new 水果()」是一匿名(沒有名稱)的水果物件,其值為類別裡定義的預設值 (在這裡例子裡我沒有訂定預設值,所以會是 int 和 string 被實體化的預設值: 0 和空字串)。
對 new 有一點概念了再來看看這個
MessageBox.Show( new DateTime().ToString() );
// 對話框裡顯示: 0001/01/01 AM 12:00:00
- 「new DateTime()」 是一 DateTime 物件,其值為預設值 0001/01/01 AM 12:00:00
- 「new DateTime().ToString()」 是一 string 物件, ToString() 方法是以前面的 DateTime 物件回傳一 string 物件 (下一章節會詳敘)
- MessageBox.Show( new DateTime().ToString() ) 滿足其執行方法的條件 (傳入一 string 物件) 所以可以成功執行這行程式。
回到原本的程式,再來看第九第十行:
我的蘋果.價格 = 1000;
- 「我的蘋果.價格」是一 int 物件,其值為 0, 剛剛被創造(實體化)出來
- 「1000」是一匿名(沒有名稱)的 int 物件,其值為 1000 (ㄜ 這句還蠻廢話的XD)
- 等號左邊和右邊的類別一致,所以可以成功指派「我的蘋果.價格」的值
我的蘋果.滋味 = "酸酸甜甜的";
- 「我的蘋果.滋味」是一 string 物件,其值為空字串,剛剛被創造(實體化)出來
- 「"酸酸甜甜的"」是一匿名(沒有名稱)的 string 物件,其值為 酸酸甜甜的
- 等號左邊和右邊的類別一致,所以可以成功指派「我的蘋果.滋味」的值
更多常見的物件屬性的用法:
// 更新已存在的 Label物件 「myLabel」 的 Text 屬性
myLabel.Text = "你好,我是遊隼";
// 從已存在的 DataGridView物件 「myTable」 取出第一橫列 (Rows[0] 屬性)
// 並存到新的 DataGridViewRow物件 「myRow」裡
DataGridViewRow myRow = myTable.Rows[0];
// 從已存在的 DataGridViewRow物件 「myRow」 取出第一格 (Cells[0] 屬性)
// 並存到新的 DataGridViewCell物件 「myCell」裡
DataGridViewCell myCell = myRow.Cells[0];
// 對話框將顯示 DataGridViewCell物件 「myCell」 的值 (Value 屬性)
MessageBox.Show($"{myCell.Value}");
// 把上面三行的程式碼寫成一行
// 從已存在的 DataGridView物件 「myTable」 取出第一橫列 (Rows[0] 屬性)
// 再取出第一格 (Cells[0] 屬性)
// 再取出值 (Value 屬性)
MessageBox.Show($"{myTable.Rows[0].Cells[0].Value}");
小技巧:Virtual Studio 以及絕大部分的 IDE (開發工具) 都可以通過滑鼠停留一陣子,就可以知道該物件是什麼類別。
using System;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
static class Program
{
/// 應用程式的主要進入點。
static void Main()
{
水果 我的蘋果 = new 水果(){ 價格 = 1000, 滋味 = "酸酸甜甜的" };
我的蘋果.打九折();
MessageBox.Show($"價格: {我的蘋果.價格}" +
$"\n嗯~吃起來: {我的蘋果.滋味}");
}
}
public class 水果
{
public int 價格;
public string 滋味;
public void 打九折()
{
價格 = (int)(價格 * 0.9);
}
public void 打八折()
{
價格 = (int)(價格 * 0.8);
}
}
}
水果 我的蘋果 = new 水果(){ 價格 = 1000, 滋味 = "酸酸甜甜的" }; |
水果 我的蘋果 = new 水果(); 我的蘋果.價格 = 1000; 我的蘋果.滋味 = "酸酸甜甜的"; |
public void 打九折() { 價格 = (int)(價格 * 0.9); } |
TIP: 只有方法會做事
一般狀況下,執行程式的地方永遠只有方法裡面。新手再複製程式碼的時候常常會把程式碼貼在 class 底下,想當然就會報錯。
namespace WindowsFormsApp1
{
int x = 0; // 不可以直接在命名空間裡宣告
public class 測試用類別()
{
int y = 0; // 可以在類別裡宣告 「y」被視為「測試用類別」的一項屬性
y = y++; // 不可以在類別裡做運算、指派等等
MessageBox.Show($"{y}"); // 呼叫方法當然也不行
public void 我的方法()
{
int z = 0; // 可以在方法裡宣告
z++; // 可以在方法裡做運算、指派等等
MessageBox.Show($"{z}"); // 也可以呼叫方法
}
}
}
- 其實也很好理解,可以在 Main() 中先實體化測試用類別。
測試用類別 測試用物件 = new 測試用類別(); - 然後就可以如下這樣用到這些程式碼。但 y = y++; 這幾行永遠不會被用到。
測試用物件.y = 1000;
測試用物件.我的方法();TIP: 方法回傳自己 (this)
原本程式碼 水果 類別中的「打九折()」方法是不回傳東西 (void):
using System.Windows.Forms;
namespace WindowsFormsApp1
{
static class Program
{
/// 應用程式的主要進入點。
static void Main()
{
水果 我的蘋果 = new 水果(){ 價格 = 1000, 滋味 = "酸酸甜甜的" };
我的蘋果.打九折().打九折(); // 程式會報錯
}
}
public class 水果
{
public int 價格;
public string 滋味;
public void 打九折() // 打九折()做完不回傳東西 (void)
{
價格 = (int)(價格 * 0.9);
}
}
}
- 「我的蘋果」打九折一次之後後面就無法接任何東西了 (因為 void 不回傳東西)
我的蘋果.打九折().打九折(); // 程式會報錯 - 但回傳的也是水果物件的話就可以一直接著下去
因為「我的蘋果」是一 水果 物件
using System.Windows.Forms;
namespace WindowsFormsApp1
{
static class Program
{
/// 應用程式的主要進入點。
static void Main()
{
水果 我的蘋果 = new 水果(){ 價格 = 1000, 滋味 = "酸酸甜甜的" };
我的蘋果.打九折().打九折(); // 程式不會報錯
}
}
public class 水果
{
public int 價格;
public string 滋味;
public 水果 打九折() // 打九折()做完後回傳一水果物件
{
價格 = (int)(價格 * 0.9);
return this; // 把自己 (this) 回傳回去
}
}
}
「我的蘋果.打九折()」也是一 水果 物件
「我的蘋果.打九折().打九折()」也是一 水果 物件
int 新價格 = 我的蘋果.打九折().打九折().價格; // 程式不會報錯 - 在這個情況中,個人更推薦在程式碼最後回傳水果物件 (因為打完折後的水果還是水果)
public class 水果
{
public int 價格;
public string 滋味;
public 水果 打九折()
{
價格 = (int)(價格 * 0.9);
return this;
}
public 水果 打八折()
{
價格 = (int)(價格 * 0.8);
return this;
}
}
static class 打折
{
public static string 標語 = "老闆跳樓大拍賣";
public static int 五折(int 原價)
{
return (int)(原價 * 0.5);
}
}
水果 我的蘋果 = new 水果(); // 一般類別可以被實體化成多個物件 水果 我的梨子 = new 水果(); 水果 我的鳳梨 = new 水果(); 打折 新打折 = new 打折(); // 靜態類別無法實體化(被創造出來) |
string 水果滋味 = 水果.滋味; // 水果還沒被實體化 // 程式不知道你的水果指是香蕉還是芭樂 string 我的標語 = 打折.標語; // 靜態物件直接用就可以了 |
打折.五折(88888); // 回傳值為 44444 |
using System.Windows.Forms; namespace WindowsFormsApp1 { static class Program { /// 應用程式的主要進入點。 static void Main() { 水果 我的蘋果 = new 水果 { 價格 = 1000, 滋味 = "酸酸甜甜的" }; 我的蘋果.打九折().打九折(); MessageBox.Show($"蘋果價格: {我的蘋果.價格}" + $"\n嗯~吃起來: {我的蘋果.滋味}"); 我的蘋果.價格 = 打折.五折(我的蘋果.價格); MessageBox.Show($"夭壽,{打折.標語}" + $"\n蘋果最終價格: {我的蘋果.價格}"); } } public class 水果 { public int 價格; public string 滋味; public 水果 打九折() { 價格 = (int)(價格 * 0.9); return this; } public 水果 打八折() { 價格 = (int)(價格 * 0.8); return this; } } static class 打折 { public static string 標語 = "老闆跳樓大拍賣"; public static int 五折(int 原價) { return (int)(原價 * 0.5); } } } |