在看過C++之後,再看C#的面向對象感覺就不難了,只是有一些區別而已。那麼現在我們來看看什麼是類。類是面嚮對象語言和麪向過程語言最大的區別。然而抽象就是面向對象的基本方法。對於抽象我們一點都不陌生,因爲抽象是人類認識問題的基本手段之一。抽象是指對具體問題進行概括,抽出一類對象的公共性質並加以描述的過程。一般一個問題的抽象應該包含兩個方面:數據抽象和行爲抽象。於是在面嚮對象語言,就引入了類的概念,所以說類就是數據抽象和行爲抽象的集合。也就是說類就相當於,一個模具。我們可以通過這個模具製造出很多一樣的產品。而這個產品就是對象。換而言之,對象就是類的具體化。由於類和對象的加入,使得我們的開發效率大大提高。下面我們來看看類的具體內容吧。
1、類定義
使用class關鍵字來聲明類,其和C++不同的地方是在大括號之後不需要冒號
class 類名
{
//類的內部
} //C++這裏有一個冒號,而C#沒有
2、類成員
3、字段與屬性
首先我們先區分一下C#數據成員中的字段、常量與事件成員。字段、常量是與類的相關變量。事件是類的成員,在發生某些行爲時(如:改變類的字段或屬性,或進行某種形式的用戶交互操作),它可以讓對象通知調用方。
那麼現在我們在來看看字段與屬性,屬性的定義如下:
[訪問權限] [類型] [屬性名稱]
{
//get和set前訪問屬性默認爲public
get
{
return [該屬性對應的字段];
}
set
{
//作你想對該字段進行的操作
}
}
下面我們來看看,實例,順便了解一下get和set的原理
【C#】
class Test
{
private int num;
public int Num
{
public get
{
return num;
}
public set
{
num = value;
}
}
}
【C++】
class Test
{
private int num;
public int getNum()
{
return num;
}
public void setNum(int value)
{
num = value;
}
}
不知道你發現了沒有,在C#中,將getNum這個函數做成了get,setNum做成了set,將set得到的值用value保存。其實說白了,屬性就是可以對某一字段進行讀取和賦值操作的方法。但是調用的時候就不需要方法名稱後的括號。就以上面的代碼爲例: Test.Num 。只要這樣就可以調用他了。
4、方法
其實這個和就是成員函數,不過在C#中成員函數的範圍更廣。現在我們來看看
<1>方法的定義
[訪問屬性] [返回值類型] 方法名稱([參數])
{
//方法內部實現
}
舉個例子:
class Test
{
private int a,b;
public int Add()
{
return a + b;
}
}
<2>調用方法:
using System;
namespace MyFirstProgram
{
class Program
{
class Test
{
private int a,b;
public int Add()
{
return a + b;
}
}
static void Main()
{
Test p = new Test();
p.Add(); //對方法的調用
}
}
}
<3>給方法傳遞參數
這個就和普通的函數傳遞參數是一樣的。在C#中,特別注意,除非特別聲明,否則引用類型均爲引用傳遞,值類型均爲值傳遞。
<4>可選參數
其實這個就是C++中的默認值
<5> ref 與 out 參數
值傳遞的類型是默認的,但是有些時候我們需要對他進行改變。這時就出現了 ref 與 out。
public void Add(ref int b)
{
b++;
}
調用時還需要添加ref關鍵字
p.Add(ref i);
其實這就和C++中的引用機制一樣,不同的是,在C#中 ref 必須 要使用賦過值的變量。然而out爲前綴時,變量可以不初始化。
特別注意:ref 與 out 的 參數不能帶有默認值:
public void Add(ref int b = 2) //錯誤,對其進行默認值,所以不能用ref或out
{
b++;
}
<6>無序傳遞
這個機制,在C++中沒有。不過覺得貌似也沒什麼用
//函數
string setName(string FName,string LName){
return FName + " " + LName;
}
//正常調用
setName("John","Doe");
//無序調用
setName(LName: "Doe", FName: "John");
兩種調用得到的結果是一致的。5、構造函數
構造函數是在創建對象時,對對象數據初始化的方法。其方法名稱與類名相同,且沒有返回類型。如果沒有寫的話,編譯器會自動創建一個無參構造函數,將所有的數據初始化爲標準的默認值。
class Test
{
//只要創建了無參構造函數,後臺將不會自動生成構造函數
public Test()
{
//構造函數實現
}
//重寫構造函數
public Test(int Number)
{
//構造函數內部實現
}
}
C#還有一個特性是可以給類編寫無參數的構造函數,編寫靜態構造函數的原因就是,類內部有一些靜態字段和屬性,需要在第一次使用類之前初始化。注意:靜態構造函數至多隻運行一次。
6、匿名類型
由關鍵字var聲明,其隱式類型化的變量。其實我覺得這個就相當於一個沒有名稱的類一樣。這個感覺並不好用,所以還是慎用。聲明如下:
如果一個對象包含一個人的姓名。
var person = new { FirstName = "John", LastName = "Doe" };
7、部分類
使用 partial 關鍵字可以將類、結構方法或藉口放在多個文件中,通常一個類在一個文件中,但是在多人開發的時候就可以體現出partial的威力了。
8、弱引用
這個機制,是爲了節約內存。因爲當程序實例化一個類或結構時,只要有代碼引用就會,形成強引用(相對弱引用而言)。如果這個類十分巨大,且不經常訪問。那麼就會浪費大量的內存,所以就引入了弱引用的概念。弱引用是使用WeakReference 類創建的。因爲對象隨時可能被回收所以在引用該對象時必須先確認它的存在。
static void Main()
{
WeakReference TestReference = new WeakReference(new Test());
Test tmp;
//IsAlive這個屬性的目的就是TestReference的對象被回收了沒有
if (TestReference.IsAlive)
{
//如果類對象存在,那就引用該對象
tmp = TestReference.Target as Test;
}
}
9、靜態類
靜態類的內部只用靜態的方法和屬性。靜態類在功能上與 使用私有靜態構造函數創建的類相同。注意:靜態類不能創建實例。
反之我們可以使用static關鍵字檢查是否創建了該類的實例,如果是編譯器就會報錯。
10、類(class)與結構(struct)的區別
①類可以繼承,然而結構不能
②類儲存在託管堆上,然而結構儲存在棧上(所以結構存儲效率優於類)
③類是引用類型,而結構是值類型
④原則結構的默認無參構造函數不可替換,但是如果將無參構造函數重寫是對全體數據成員進行賦值的話,那麼就可以重寫
11、只讀字段與常量的區別
只讀屬性有readonly聲明。常量概念就是包含一個不可修改的變量。但是有時候需要一些變量其值不能改變,但運行之前是未知的。所以我們就引入了只讀屬性。只讀屬性比const靈活很多,readonly可以再構造函數中給其賦值,所以說每個實例都可以有不同的值。
12、typeof的使用
typeof可以獲取對象類型,
Type t = typeof(int);
Console.WriteLine(t.Name);
這樣的話就會輸出Int3213、using的使用
在C#中using就和C++的typedef一樣:
using Print = System.Console;
namespace MyFirstProgram
{
class Program
{
static void Main()
{
Print.WriteLine("Hello world!");
}
}
}
第三章的內容差不多就是這樣