創作內容

5 GP

【物件懶人包:類別、屬性、方法 C#筆記】

作者:游隼│2021-09-09 12:27:11│巴幣:10│人氣:1581
鑒於班上蠻多人對物件的類別、屬性、方法等基礎但有很重要的觀念不是很熟悉,特別寫這篇文章 (懶人包) ,這篇只是給一個大概的觀念,其他也很重要的如繼承、存取修飾詞等,這裡不會講,翻書本跟查網路上的教學是更好的做法。


目錄


  • 物件類別:物件的設計藍圖 
  • 物件屬性:物件中的物件
  • 物件方法:真正執行程式的地方
  • 靜態類別:獨一無二的物件
  • 總結:萬物皆物件
  • 這篇教學的完整程式碼


物件類別:物件的設計藍圖


我用 C# 做示範 其他物件導向語言也是大同小異

首先先從簡單的開始 最常見的字串物件。其中 string 就是一種類別 (class)。
string myString;
  • 第一行程式碼宣告了一個名為 myString 的字串物件,因為尚未指派其值,會讀出 null
  • 更口語的說法:「使(宣告) myString 成為一 string 物件」
  • 所以 myString 是個物件,而 string種類別
  • myString 沒有被宣告成 const, 亦即 myString 的值是可以被更新/取代的。所以 myString 同時也是個變數

再來,我隨便找了幾種 DateTime, DataTable, Button, List<string>,他們也都是類別,注意下列程式碼都還尚未指派其值 (其值通常為 null)。
DateTime myTime;
DataTable myTable;
Button myButton;
List<string> myStringList;
  • 第一行「使 myTime 成為一 DateTime 物件」
  • 第二行「使 myTable 成為一 DataTable 物件」
  • 第三行「使 myButton 成為一 Button 物件」
  • 第四行「使 myStringList 成為一 List<string> 物件」
上面的例子,都是 C# 內建,或是由 using指示詞 匯入的類別。接下來我們來創造一種自己定義的 Class (物件類別)。


物件屬性:物件中的物件


下面範例定義了一水果」物件,每個水果都有兩個屬性:價格、滋味。
public class 水果
{
    public int 價格;
    public string 滋味;
}
  • 第一行「使 水果 成為一種物件類別(class)
  • 第三行「使 價格 成為一 int 物件」同時「價格 是 水果 的一屬性(在 class 水果的底下)
  • 第四行「使 滋味 成為一 string 物件」同時「滋味 是 水果 的一屬性(在 class 水果的底下)
  • public 是存取修飾詞代表「公用」(哪裡都可以存取), 不是今天的主題這裡不講

現在我們有了「水果」這種物件類別了(我們有了「水果」的設計圖),接下來就是把它給創造出來。
static class Program
{
    /// 應用程式的主要進入點。
    static void Main()
    
{
        
水果 我的蘋果; // 把水果設計圖拿給「我的蘋果」
        我的蘋果 = new 水果(); // 依水果設計圖做出「我的蘋果」

        我的蘋果.價格 = 1000;
        我的蘋果.滋味 = "酸酸甜甜的";
        MessageBox.Show($"價格: {我的蘋果.價格}" +
            $"\n嗯~吃起來: {我的蘋果.滋味}");
        // 對話框裡顯示 價格:1000 嗯~吃起來:酸酸甜甜的
    }
}
  • 第六、七行成功的將「我的蘋果」創造出來,這時我們還沒設定「我的蘋果」的屬性「價格」和屬性「滋味」。
  • 第九、十行將「我的蘋果」正確的屬性「價格」跟屬性「滋味」給放到了「我的蘋果」中。

TIP: 新手容易出錯的指派運算子 以及 new 運算子


指派運算子 (=) 有一個很好理解又很容易被忘記的特性:指派 (等號右邊) 的物件和被指派 (等號左邊) 的物件兩者類別通常皆須一致。上面程式碼第六行:
我的蘋果 = new 水果();
  • 指派運算子左邊的「我的蘋果」是一水果物件,其值為空。
  • 指派運算子左邊的「new 水果()」是一匿名(沒有名稱)水果物件,其值為類別裡定義的預設值 (在這裡例子裡我沒有訂定預設值,所以會是 intstring 被實體化的預設值: 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);
        }
    }
}
  • 可以看到要被運行的程式碼被包在了一個靜態類別(下一章節會再說明,知道他是一種 class 類別即可) Program 底下的 Main() 方法。
  • Program 底下的 Main() 方法是 C# 程式的主要進入點 (程式一運作第一個執行的地方)
  • 第十一行在創造「我的蘋果」的同時塞入了屬性
  • 水果 我的蘋果 = new 水果(){ 價格 = 1000, 滋味 = "酸酸甜甜的" };
    這裡的程式碼就等於
    水果 我的蘋果 = new 水果();
    我的蘋果.價格 = 1000;
    我的蘋果.滋味 = "酸酸甜甜的";
  • 倒數第十行「打九折()」是 水果 類別中的一個方法,會把水果的「價格」*0.9後再轉成 int 物件再存回屬性「價格」裡 (價格乘以 0.9 後會變 double(雙精度小數) 類別)
    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 我的標語 = 打折.標語; // 靜態物件直接用就可以了
  • 所以程式一開始執行的地方 Program 是一靜態類別,因為 Program 不會再被實體化成 Program1,  Program2...... 等等。
  • 視窗 (WinForm) 不是靜態類別 所以可以開啟同一個視窗很多次,這是被允許的。
  • 常見的 MessageBox 就是一靜態類別。MessageBox.Show() 是該靜態類別裡的一靜態方法。
  • 倒數第五行的靜態方法「五折()」要求一個 int 引數 (執行方法須傳入的物件稱為引數),並且會回傳一 int 物件。
    打折.五折(88888); // 回傳值為 44444


總結:萬物皆物件


有沒有發現物件導向語言就是操作一大堆物件的過程,所有的東西都是一個個物件,如果領悟會了這一句話,那也會一半了 (不要瞎掰好嘛XD)

接下來就是遇到一堆沒有看過的物件類別,遇到沒看過的物件類別也只有一個方法,就是查。因為這些物件類別不是自己寫的,也不可能都只用自己創造的物件類別,必須查了才知道裡面有什麼屬性/方法可以用。

小技巧:Virtual Studio 以及絕大部分的 IDE (開發工具) 都可以通過一個點來查看這個物件可以用什麼屬性/方法。


這篇懶人包的完整程式碼


可以用 Visual Studio 建一 Windows Form 應用程式,將下列程式碼貼至 Program.cs 中執行。
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);
        }
    }
}
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=5261380
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 0 篇留言

我要留言提醒:您尚未登入,請先登入再留言

5喜歡★ding890326 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:【discord.js ... 後一篇:測試用測試用...

追蹤私訊切換新版閱覽

作品資料夾

as88724香菇
畫畫好難啊..(☍﹏⁰)看更多我要大聲說1小時前


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】