本章用詞:

徑物:代表一個路徑上的資料夾或檔案。

資料夾:和「目錄」是同一個意思。

 

路徑的處理:

其利用到一個Path類別(注意,是「Path類別」而不是「Path類別物件」)。其用法有(以下的路徑,可為絕對路徑、也可為相對路徑。而路徑上若不存在徑物,執行時也不會出現錯誤):

Path.GetFullPath(String "路徑"):回傳一個字串。乃是該路徑的絕對路徑形式。

Path.GetPathRoot(String "路徑"):回傳一個字串。乃是該路徑的根目錄所在。

Path.GetDirectoryName(String "路徑"):回傳一個字串。乃是該路徑上徑物,其所屬之資料夾的絕對路徑。

Path.GetFileName(String "路徑"):回傳一個字串。乃是該路徑上徑物的名稱。

Path.GetExtension(String "路徑"):回傳一個字串。乃是該路徑之徑物的副檔名。若該路徑上的徑物是資料夾,則回傳空字串。

Path.GetFileNameWithoutExtension(String "路徑"):回傳一個字串。乃是該路徑上徑物的名稱(不包含副檔名)

 

 

上一篇:資料夾的處理

下一篇:檔案的處理

按此前往C#完整教學目錄

文章標籤

埃伯 發表在 痞客邦 留言(0) 人氣()

 

 

(1) 其利用到一個DirectoryInfo物件。此物件代表著作業系統中某一個資料夾路徑的相關資訊。該物件的宣告方法為:

DirctoryInfo 物件名稱 = new DirwctoryInfo(String "路徑");

其中,路徑可為絕對路徑或相對路徑。若為相對路徑,則以該專案的執行檔所在之路徑為基準。這個該專案的執行檔所在之路徑」,通常為該專案資料夾下的:專案名稱\bin\Debug。例如某個專案名叫WindowsFormsApplication1,則這個「該專案的執行檔所在之路徑」就是該專案資料夾下的:WindowsFormsApplication1\bin\Debug

且在輸入相對路徑時,可用點號 . 來代表當前目錄,用兩個點號 .. 來代表當前目錄的父目錄。

  1. DirectoryInfo物件的常用成員:

物件名稱.FullName:一個string。代表該路徑絕對路徑形式。

物件名稱.Exists:一個bool。若為true,代表該路徑上已有資料夾存在。若為false則代表該路徑上沒有徑物存在、或存在的徑物不是資料夾。

物件名稱.CreationTime:一個DateTime物件。代表該路徑上之資料夾創立的時間。若該路徑上之徑物不是資料夾,也會顯示其創立的時間。但若該路徑上沒有徑物,則其時間會是1601/1/1 08:00:00

物件名稱.LastAccessTime:一個DateTime物件。代表該路徑上之資料夾最近一次被存取的時間。若該路徑上之徑物不是資料夾,也會顯示其最近一次被存取的時間。但若該路徑上沒有徑物,則其時間會是1601/1/1 08:00:00

物件名稱.Parent:一個DirectoryInfo物件。代表該路徑之父目錄的相關資訊。

物件名稱.Name:一個string。代表該路徑上之徑物名。

(2) DirectoryInfo物件的常用成員函式:

物件名稱.Create():無回傳值。若路徑上沒有徑物,此函式會在路徑上建立一個空的資料夾。而若路徑上有徑物,則此函式不作用。

物件名稱.CreatSubdirectory(String "名稱"):若路徑上沒有徑物、或路徑上的徑物是資料夾,則此函式會在路徑底下建立一個空的子資料夾,其名稱為名稱,並回傳一個將該子資料夾的DirectoryInfo物件。而若路徑上的徑物不是資料夾,則此函式會出錯。

物件名稱.Delete():無回傳值。若路徑上的徑物是資料夾,則此函式會刪除此資料夾。而若路徑上無徑物、或徑物不是資料夾,則此函式會出錯。

物件名稱.GetDirectories([String 檔名條件]):若路徑上的徑物是資料夾,則此函式會回傳一個DirectoryInfo物件的矩陣,而若路徑上無徑物、或徑物不是資料夾,則此函式會出錯。若沒寫檔名條件則回傳該路徑中所有子資料夾的相關資訊。若有寫檔名條件,則回傳符合該檔名條件所有子資料夾。檔名條件也支持萬用字元*的用法。例如,在dir1資料夾下有三個子資料夾dd1dd2hh。則:

物件名稱.GetDirectories()會回傳這三個子資料夾之DirectoryInfo物件的矩陣。

物件名稱.GetDirectories("dd1")回傳矩陣中的元素,就只有dd1這個子資料夾之DirectoryInfo物件。

物件名稱.GetDirectories("dd*")會回傳dd1dd2DirectoryInfo物件的矩陣。

物件名稱.GetFiles([String 檔名條件]):若路徑上的徑物是檔案,則此函式會回傳一個FileInfo物件的矩陣,代表該路徑中所有子檔案的相關資訊。而若路徑上無徑物、或徑物不是資料夾,則此函式會出錯。若沒寫檔名條件則回傳該路徑中所有子檔案的相關資訊。若有寫檔名條件,則回傳符合該檔名條件所有子檔案。檔名條件也支持萬用字元*的用法。

物件名稱.MoveTo(String "新路徑"):無回傳值。將該資料夾從原本的路徑移至新路徑上。但若新路徑上已經有徑物存在,則此函式會出錯。

(2) 資料夾的常用功能:

Directory.Exists("路徑"):檢查路徑上是否有資料夾。若有回傳true,否則回傳false。注意,若路徑上的徑物是檔案而非資料夾,也會回傳false

Directory.Delete("路徑", B):刪除該路徑上的資料夾。其中B是布林值,表示是否要遞迴式的刪除路徑資料夾裡面的子資料夾。若路徑上的資料夾內容不為空,則B要設為true,否則設為false。表示要若路徑上無資料夾,本函式會出錯。

Directory.CreateDirectory("路徑"):建立資料夾在路徑上。

 

 

 

上一篇:類別的繼承

下一篇:路徑的處理

按此前往C#完整教學目錄

文章標籤

埃伯 發表在 痞客邦 留言(0) 人氣()

類別的繼承

 

1. 子類別與父類別:

子類別(又稱「衍生類別」)和父類別(又稱「基礎類別」)這兩個名詞,隨著「繼承」這個動作的發生,而一起被定義。我們稱繼承者是子類別,被繼承者是父類別。「子類別繼承父類別」這句話,其意義是「父類別將自己的publicprotected的成員與成員函式傳遞給子類別,使子類別在宣告時不必宣告這些成員、成員函式,就能擁有他們」。

子類別的宣告式:

class 子類別名稱 : 父類別名稱

{

    類別成員宣告式

    類別成員函式宣告式

    類別建構式    

};

註:在子類別宣告式之內,可用this關鍵字來代表類別本身,而用base關鍵字來代表其父類別(可用base.成員base.成員函式名稱(參數一,參數二…)來呼叫父類別的成員與成員函式)。

再次強調,父類別中能夠被繼承的只有「publicprotected的成員與成員函式」。而父類別的建構式,就算其為public也不能被子類別繼承。子類別之建構式的寫法與一般類別不同(與其父類別的建構式有關),語法為:

存取修飾詞 子類別名稱(參數資料型態一 參數一, 參數資料型態二, 參數二…) : base(父類別建構式參數一, 父類別建構式參數二…)

{

//函式內容(可以不需對賦類別建構式參數進行設定)

}

此語法之形式不易理解,可參考範例:

class person    

{

      public string name;

      public int age;

      public person(string n_, int a_) 

      { name = n_; age = a_; }

      public string self_introduction()

 { return "hi, I'm " + name + "," + age + "years old."; }

};

class boy : person    //boy是一個子類別,繼承了父類別person

{

      public int money;

      public boy(string n_, int a_, int money_) : base(n_, a_)

      { money = money_; }  //子類別建構式在此

};

boy b1 = new boy("Jack", 12, 200);  //子類別物件之宣告,仍按照子類別建構式的寫法

 

2. 在子類別重新定義父類別成員函式:

當子類別從父類別繼承了某個成員函式,但卻想改寫這個成員函式時(這個「改寫」,並不會影響父類別物件對該成員函式的使用,而是重新在子類別中定義該成員函式,以供子類別自己所用),有以下兩種方法:

(1) 子類別覆寫父類別的虛擬成員函式:

要成功使用這個方法的前提是:父類別中那個要被重新定義的成員函式,是個「虛擬函式」。虛擬函式的寫法需利用到virtual關鍵字,如下:

存取修飾詞 virtual 回傳資料型態 虛擬成員函式名稱(參數資料型態一 參數一, 參數資料型態二, 參數二…)

{

//函式內容

}

而在子類別中,覆寫該虛擬函式需利用override關鍵字。語法如下:

存取修飾詞 override 回傳資料型態 虛擬成員函式名稱(參數資料型態一 參數一, 參數資料型態二, 參數二…)

{

//函式內容

}

※ 範例如下:

class A

{ public virtual string intro(){ return "this is A";}};

class B : A

{ public override string intro(){ return "this is B"; }};

B b1 = new B();

textBox1.Text = b1.intro();   //顯示this is B

(2) 子類別成員函式直接取代父類別成員函式:

這種方法比較方便,直接在子類別中利用new關鍵字宣告欲取代的成員函式。語法為:

存取修飾詞 new 回傳資料型態 虛擬成員函式名稱(參數資料型態一 參數一, 參數資料型態二, 參數二…)

{

//函式內容

}

※ 範例如下:

class A

{ public string intro(){ return "this is A";}};

class B : A

{ public new string intro(){ return "this is B"; }};

B b1 = new B();

textBox1.Text = b1.intro();   //顯示this is B

 

3. 父類別物件與子類別物件的轉換:

(1) 父類別物件,不能顯性轉換為子類別物件。

(2) 子類別物件,可以顯性轉換為父類別物件。只不過轉換之後,在該子類別內另行定義的成員和成員函式,將會消失。只有繼承父類別的成員和成員函式會保留下來。顯性轉換的方法為:

(父類別名稱)子類別物件名稱

如,今有一個person類別和一個man類別(man 類別繼承person類別,故person是父類別相對於man是子類別),一個man類別物件名為wang,則:

person jili_wang = (person)wang;

即可將wang轉成person類別後,儲存在jili_wang這個perosn類別物件裡。

 

4. 抽象類別與抽象成員函式:

所謂抽象成員函式」,指的是在該成員函式被宣告時,只有宣告其名稱、回傳資料形態、參數列,卻沒有宣告函式內容(函式內容不在類別本身中宣告,而是在該類別之衍生類別中再去覆寫)。而若某個類別擁有抽象成員函式,就稱其為「抽象類別」(抽象成員函式也只能在抽象類別中宣告)。抽象類別並不能被用來建立物件,而是專門被用來繼承的。這種用法,在較大、複雜的類別架構中,能使程式碼更為簡潔易讀。

抽象類別與抽象成員函式均用到關鍵字abstract。其宣告如下:

(1) 抽象類別的宣告:

abstract class 類別名稱

{

    類別成員宣告式

    類別成員函式宣告式

    類別建構式    

};

(2) 抽象成員函式的宣告:

abstract 存取修飾詞 回傳資料型態 成員函式名稱(參數資料型態一 參數一, 參數資料型態二, 參數二…)

※ 註:抽象類別中可以沒有抽象成員函式,但有抽象成員函式的類別一定要宣告成抽象類別,否則程式執行時會出錯。

(3) 抽象成員函式的實作:

抽象成員函式的函式內容不在抽象類別本身中宣告,而是在該抽象類別之衍生類別中去覆寫。「為抽象成員函式寫入函式內容」這個動作,稱為對抽象成員函式的「實作(implement)」。

如以下範例:

abstract class person

{

      public string name;

      public int age;

      public person(string n_, int a_)

      { name = n_; age = a_; }

      abstract public string talk();       //抽象成員函式talk()在此   

};

class teacher : person  

{

      public teacher(string n_, int a_)

          : base(n_, a_){ }

      public override string talk()   //實作抽象成員函式talk()

      { return "Hi, My name is " + name + ", nice to meet you!"; }

};

class waiter : person

{

      public waiter(string n_, int a_)

          : base(n_, a_){  }

      public override string talk()    //實作抽象成員函式talk()

      { return "Welcome to our bar. Need something?"; }

};

由上範例可知,每個衍生類別對於抽象成員函式都有不同的實作方法,就如同生活中對於每種不同的人(person)進行交談(talk)時,他們的回話都不盡相同。這就是抽象成員函式在應用上的意義。

 

 

 

上一篇:類別物件的複製

下一篇:資料夾的處理

按此前往C#完整教學目錄

文章標籤

埃伯 發表在 痞客邦 留言(0) 人氣()

類別物件的複製:

(1) 設今有person類別如下:

class person

{

      public string name;

      public int age;

      public person(string n_, int a_)  //建構式在此

      { name = n_; age = a_; }

      public string self_introduction()

            { return "hi, I'm " + name + "," + age + "years old."; }

};

且已宣告一個person類別物件p1

person p1 = new person("weiwei", 18);

那麼要如何複製p1呢?

並不是只用person p2 = p1;就可複製p1,因為C#類別物件事實上只是個參考,並非實體。也就是說,p2p1參考同一個物件,所以改變p2的同時也會改變p1。證明如下:

            person p1 = new person("weiwei", 18);

            person p2 = p1;

            p2.name = "nunu";

            richTextBox1.Text = p1.name.ToString();

則程式執行完成後,richTextBox1.Text之值會是nunu

(2) 要在C#中執行真正的複製,也就是複製一個與原先物件有相同成員值、成員函數,但互相獨立、彼此互不影響的物件,必須用「深複製(deep copy)」方法。也就是說在類別中自寫一個函式,可回傳一個相同類別物件,而此類別物件與本物件一模一樣。如在person類別中,寫下deep_copy()函式

                  public person deep_copy()

            {

                person new_person = new person(this.name, this.age);

                return new_person;

            }

然後:

            person p1 = new person("weiwei", 18);

            person p2 = p1.deep_copy();

            p2.name = "nunu";

            richTextBox1.Text = p1.name.ToString();

則程式執行完成後,richTextBox1.Text之值還是weiwei

(3) 深複製並非只有這麼簡單,若碰上更複雜的類別,那就會變得更麻煩。如在上例中再加上一個kingdom類別:

class kingdom

{

public person king;

public person queen;

public List<person> worker = new List<person>();

public string name;

public string history;

public int money;

public kingdom(string name_)

{ name = name_; }           

}

那麼在寫深複製函式之前,要先搞清楚哪些成員是類別物件,要先為這些成員寫深複製函式才行。kingdom類別的深複製函式如下:

            public kingdom deep_copy()

            {

                kingdom new_k = new kingdom(this.name);

                new_k.king = this.king.deep_copy();

                new_k.queen = this.queen.deep_copy();

                new_k.worker = this.worker.ToList();

                new_k.history=this.history;

                new_k.money = this.money;

                return new_k;

            }

然後利用下列程式碼測試:

            kingdom k1 = new kingdom("AAA");

            k1.king = new person("king.AAA", 50);

            k1.queen = new person("queen.AAA", 40);

            k1.worker.Add(new person("w1.AAA", 20));

            k1.worker.Add(new person("w2.AAA", 25));

            k1.history = "AAA's history";

            k1.money = 100;

 

            kingdom k2 = k1.deep_copy();

            k2.king = new person("king.BBB", 50);

            k2.queen = new person("queen.BBB", 40);

            k2.worker.Add(new person("w1.BBB", 20));

            k2.worker.Add(new person("w2.BBB", 25));

            k2.history = "BBB's history";

            k2.money = 200;

 

            richTextBox1.Text +=

            "k1:king = " + k1.king.name + "\r\n" +

            "k1:queen = " + k1.queen.name + "\r\n" +

            "k1:worker = ";

            for (int i=0;i<k1.worker.Count;i++)

            {

                richTextBox1.Text +=k1.worker[i].name+",";

            }

            richTextBox1.Text += "\r\n" +

            "k1:history = " + k1.history + "\r\n" +

            "k1:money = " + k1.money + "\r\n";

則程式執行完成後,richTextBox1.Text之值為:

k1:king = king.AAA

k1:queen = queen.AAA

k1:worker = w1.AAA,w2.AAA,

k1:history = AAA's history

k1:money = 100

這代表深複製函式的成功。

 

 

 

上一篇:靜態成員與靜態成員函式

下一篇:類別的繼承

按此前往C#完整教學目錄

文章標籤

埃伯 發表在 痞客邦 留言(0) 人氣()

(1) 靜態成員:

所謂靜態成員,是指這個成員之值為所有同類別之物件所「共享」。靜態成員在所有類別物件裡的值都一樣,若經更改,則此靜態成員的值在所有同類別物件中也都會更改。靜態成員的宣告式,比之一般成員的宣告式,多了static關鍵字,其語法為:

存取修飾詞 static 靜態成員資料型態 靜態成員名稱 = ;

其中,存取修飾詞的寫法與類別成員宣告式中的存取修飾詞寫法相同。

靜態成員不僅屬於特定一個物件,而是屬於該類別本身。在類別外存取該類別之靜態成員的方法為(需先確定該靜態成員是public)

類別名稱.靜態成員名稱=;

範例:

class person

{

      public static int number_of_person=0;   //這就是靜態成員

      public string name;

      public int age;

      public person(string n_, int a_)

      { name = n_; age = a_; number_of_person++; }  //每宣告一次person物件,number_of_person靜態成員就會增加1

};

person p1 = new person("weiwei", 18);

person p2 = new person("nunu", 20);

textBox1.Text = person.number_of_person.ToString();   //再次提醒,靜態成員的呼叫不是類別物件名稱.靜態成員名稱,而是類別名稱.靜態成員名稱

執行後顯示:2

(2) 靜態成員函式:

靜態成員函式,只能對靜態成員進行操作、不能對一般成員進行操作。順便一提,一般的非靜態成員函式,對靜態成員、非靜態成員都可以操作。靜態成員函式的宣告式,比之一般成員函式的宣告式,多了static關鍵字,其語法為:

存取修飾詞 static 回傳資料型態 成員函式名稱(參數資料型態一 參數一, 參數資料型態二, 參數二…)

{

//函式內容

}

其中,存取修飾詞的寫法與類別成員宣告式中的存取修飾詞寫法相同。

靜態成員函式不僅屬於特定一個物件,而是屬於該類別本身。在類別外存取該類別之靜態成員函式的方法為(需先確定該靜態成員是public)

類別名稱.靜態成員函式名稱(參數一,參數二,參數三…);

 

 

上一篇:類別的「成員」與「屬性」

下一篇:類別物件的複製

按此前往C#完整教學目錄

文章標籤

埃伯 發表在 痞客邦 留言(0) 人氣()