標籤:
類及成員
類是一組對象的屬性和行為特徵的抽象描述,對象是類的執行個體。
類是抽象的,對象是具體的。 抽象是有選擇的忽略。
封裝:使資料及方法結合;控制訪問可見度。
允許控制---只能通過公用的方法來訪問對象。 允許變化---私人對象的類型發生變化也不會影響對象的使用。
待用資料描述了一個類的所有對象的資訊。
靜態方法只能訪問待用資料,通過類來訪問而不是對象。方法是公用的,資料是私人的。
聲明一個類的對象並不會建立類的對象--使用new操作符建立對象。然後用對象.方法來處理資料。 this關鍵字指向當前對象(當前類的)---當不同範圍中的名稱標識衝突時特別有用。
class BankAccout
{
.....public void SetName (string name)
{
this.name(指的是私人欄位的) = name;
}
private string name;
}
存取修飾詞:public 只要知道所在的命名空間就可進行訪問private 只對所在的類或結構可見。
常量:是一個表示恒定不變的數值的符號。
欄位: 表示一個資料的值,它或是唯讀,或是讀寫的可分為靜態欄位和執行個體欄位。初始化是可選的,初始化的值必須在編譯時間可以確定下來,結構的欄位值不能被初始化。唯讀欄位必須聲明或在建構函式中進行初始化,不一定在編譯時間就要確定下來,值不能改變。
方法:是一個函數,用來改變或查詢一個類型(靜態方法)獲知一個對象(執行個體方法)的狀態。方法一般需要讀寫類型或對象的欄位。靜態方法只能訪問待用資料(欄位)
建構函式及解構函式
建構函式首先是一個方法。
1.分配記憶體:使用new關鍵字從託管堆中分配記憶體
2.初始化對象的附加成員(方法表指標及內部保留欄位)
3.使用構造器初始化對象-使用類的名字後跟括弧。
CLR要求每個類至少定義一個建構函式。(沒有的話,編譯器會自動建立預設的建構函式)預設的建構函式的特點:pubic 存取層級;與類同名;沒有傳回型別(包括void);無參數;將所有的欄位初始化為0,FaLSE,null。
建構函式可以被重載(同範圍,同名稱,不同參數;可實現用不同的方式對對象進行初始化,可有不同的訪問限制)重載的建構函式可能包含重複的代碼。
結構的建構函式:編譯器總是產生一個預設的建構函式,預設的建構函式將所有的欄位初始化為0。結構中聲明的建構函式不會自動將欄位初始化為0,必須對所有的欄位進行初始化,不能聲明預設的建構函式,不能將聲明存取修飾詞為proctecd的函數。
私人的建構函式可以組織對象的建立,不允許用new來執行個體化新的執行個體,靜態方法不需要執行個體化類就可以使用此方法用類.靜態方法調用。
靜態建構函式用於初始化類型的靜態欄位。(不能包含存取修飾詞;必須是無參的;預設情況下,沒有靜態建構函式,定義的話也只能有一個靜態建構函式;內聯的初始化會自動產生建構函式。)不支援靜態建構函式的重載。
靜態建構函式的訪問限制私人,其調用由CLR負責。對象生命期建立對象:使用new關鍵字來分配記憶體;使用建構函式在所分配的記憶體中初始化對象。使用對象:調用對象的方法。銷毀對象:記憶體被回收。
局部變數---在方法中定義的變數解構函式是用於實現對象清理的機制。
方法及參數調用方法在同一個類中調用此方法--使用方法的名字後跟參數列表及括弧。調用其他類中定義的方法--必須同時指定包含此方法的類;被調用的方法必須聲明了相應的存取修飾詞如public。
嵌套調用--可以在方法中調用其他的方法。
局部變數:當方法開始執行時建立,對方法來說是私人的,退出方法是被銷毀。
共用變數:在類層級定義的變數時共用變數,可以被多個方法同時訪問。
範圍衝突:當局部變數與共用變數存在命名衝突時,編譯器不會警告。優先使方法內的局部變數用共用變數時要用this指定。聲明及調用參數:聲明參數--將參數放在方法名後的括弧內;為每一個參數定義參數名及類型。調用參數的方法--為每一個參數指定值。傳遞參數實值型別按值傳遞--傳遞給方法的將是實值型別執行個體的一個拷貝,調用方法中的執行個體不會受到影響。
參考型別俺值傳遞--參數的傳遞時通過傳遞指向對象的引用來完成的,引用(指標)本身是按值傳遞的;方法可以改變引用對象。
引用參數:對參數記憶體位址的引用。使用引用參數:在方法中聲明及調用時使用ref關鍵字;
變數的值及類型必須匹配;在方法內對參數所做的改變會影響到調用者;在調用方法之前必須指定參數的值。
輸出參數:參數值並不傳遞到方法內,用於向方法外而不是方法內傳遞的值,不要求必須有初始值out變長參數:使用params關鍵字,在參數列表的最後聲明,聲明一維數組,編譯時間進行匹配檢查,總是按值傳遞。
eg:static long AddList(params long[] v)
{
long total ,i;
for(i=0,total =0;i<v.Length;i++)
total+=v[i];
return total;
}
static void Main()
{
long x = AddList(63,21,84);//此地方可以繼續加參數只要別超過long型。
}
遞迴方法:方法對自己進行調用
eg:
public int factorial(int n)
{
if(n<=1)
return 1;
else
return factorial(n-1)*n;
}
方法及運算子多載
方法重載:在同一個類中具有相同名稱的方法。通過參數列表進行區分;
方法簽名:在一個類中,方法的簽名必須是唯一的,如方法的名稱,參數類型,參數個數,參數順序,參數的修飾符。
對簽名沒有影響:參數的名稱,方法的傳回型別,是否使用params,不能僅存在ref及out的差別。使用重載方法:條件:需要具有不同參數的類似的方法;要在現有的代碼上添加新的功能。不要濫用重載(調試,維護較困難)
操作符的重載(建構函式的重載)
eg:
class Vector
{
public double x,y,z;
public Vector(double x,double y,double z)
{//初始化類中的三個欄位
this.x=x; this.y=y; this.z=z;
}
public Vector(Vector rhs)
{//建構函式的重載,將類的值賦給參數rhs
x=rhs.x; y=rhs.y; z=rhs.z;
}
public override string ToString()
{
return"("+x+","+y+","+z+")";
}
public static Vector operator +(Vector lhs, vertor rhs)//操作符的重載運算子返回Vector類型
{//其參數的類型要與運算子的傳回型別相同。
Vector result = new Vector(lhs);
result.x+=rhs.x;
result.y+=rhs.y;
result.z+=rhs.z;
return result;
}
static void Main()
{
Vector vect1,vect2,vect3;
vect1 = new Vector(3.0,3.0,1.0);//執行個體化並初始值
vect2 = new Vector(2.0,-4.0,-4.0);
vect3 = vect1+vect2;//c#預設是不支援兩個對象相加,但重載過的可以。
Console.WriteLine("vect1="+vect1.ToString());
Console.WriteLine("vect2="+vect2.ToString());
Console.WriteLine("vect3="+vect3.ToString());
Console.ReadLine();
}
轉換操作符方法必須是public及static的。顯示轉換用explicit關鍵字隱士轉換用implicit關鍵字
屬性及索引器
屬性是一種(封裝)內部資訊的有效方法,保護了類內部的欄位。簡潔的使用方法,靈活性,允許更改前驗證資料,可以透明的公開類中的資料,當資料被更改時,可以採取行動,如引發事件。
屬性提供了類似於欄位的訪問:使用get訪問器方法提供讀取存取,使用set訪問器方法提供設定訪問。
eg:
class Button
{
public string Caption//Property,通過屬性方法訪問私人欄位,
//Caption屬性封裝了下面caption私人欄位
{
get{return caption;}
set{caption=value;}
}
private string caption;//Field 私人欄位
}//使用屬性
Btton button = new Button();button.Cation = "Button";//為屬性賦值
屬性,欄位區別:屬性是邏輯欄位--get訪問器方法可返回一個經過計算的值。
相似性:使用的文法類似的。不同:屬性不是值,他們沒有地址(本質上是操作欄位,對欄位進行封裝)屬性不能被當做方法的ref及out參數來傳遞。
屬性與方法區別:相似性--均包含要執行的代碼,均可用於隱藏實現的細節,均可被添加virtul,abstract,override等修飾符。不同---句法:屬性不使用括弧,語義:屬性的傳回值不可為空,也不能使用任意多的參數。靜態屬性屬於類,只能訪問待用資料。屬性的存取修飾詞:
如:將get訪問器方法聲明為public,將set訪問器方法聲明為protected(此時只能在類的內部或者衍生類別內部賦值)索引器:可以看做是智能的數組。索引器提供了針對於對象的類似於數組的訪問方式--當屬性可以具有多個值的時候非常有用。
eg:
class Sample
{
public int this [int i]//this是索引器名稱 int是索引器數值或給他賦值的值的類型。
{
get{return this.data[i];
}//返回數組data第i個座標
set{this.data[i] = value;}//將value值賦到data欄位裡
}
private int data[] = new int[10];//Field 私人的整型數組
}//使用索引器
Sample mySample = new Sample();mySample[0]=1;//0傳遞給this [int i]中的i中然後索引器再把1賦值給data數組中...
int a = mySample [2];//會調用get訪問索引器及數組的區別相似:均使用數組文法不同:索引器可以使用非整形下標,(索引器可以被重載,可以同時定義幾個使用不同索引類型的索引器,)它不是變數,沒有實際的儲存位置,不呢個將索引器作為ref和out參數傳遞
索引器與屬性的區別
相同:都使用get及set訪問器方法,都沒有地址,傳回型別都不可為空不同:索引器可以重載,索引器不能是靜態定義索引器時,需要制定至少一個索引參數,針對每一個參數均需指定一個值,不能使用ref及out參數修飾符。
委託及事件
委託:當把方法傳遞給其他方法時使用。一個方法需要對另一個方法進行操作,此時需要將第二個方法作為參數傳遞到第一個方法中。
使用委託--定義要使用的委託,即告訴編譯器這種委託類型代表了哪種類型的方法,然後建立該委託的一個或多個執行個體。聲明委託就是定義了一個類型,此類型封裝了一個有著特定參數集合即傳回值的方法的定義。
delegate void MyDelegate1(string s);//為一個方法聲明了一個委託,此方法接受一個string類型的參數,且傳回值為空白。委託相當於定義了一個新類,在定義類的任何地方都可以定義委託。執行個體化委託:使用new操作符建立委派物件。委託的建構函式總是帶有一個參數,此參數就是委託的引用的方法。
eg:將委託執行個體化為
(instantiating)MyClass類中的靜態方法
HelloMyDelegate1 a=new MyDelegate1(MyClass.Hello)//將委託執行個體化為MyClass類的對象p中的執行個體方法
AMethod MyClass P=new MyClass();
MyDelegate1 b = new MyDelegate1(p.AMethod);
調用委託//根據前面的聲明及執行個體化過程,下面的語句調用了MyClass類中的靜態方法Hello,使用了參數Worlda("World");委託的特徵委託的執行個體可以是任何類型的任何對象上的執行個體方法或靜態方法,只要方法的特徵匹配與委託的特徵即可。
多播委託:委託可以包括多個方法,調用時就可以按順序連續調用多個方法,委託的簽名必須返回voidMyDelegate a,b,c,d;a= new MyDelegate(Foo);b= new MyDelegate(Bar);c = a+b;//a和b聯合成c委託,c是多播委託d = c-a;//把a委託從c中減去,則d委託只引用b委託Bar方法a+=b;//a是多播委託a-=b;//a又變成了單播委託
事件--對象間的通訊介質,在.net中使用委託來對事件進行封裝處理。聲明事件的委託類型。加上event關鍵字還得加上委託
eg:
public delegate void MouseClicedEventHandler();
public class Mouse
{
public static event MouseClickedEventHandler MouseClicked;
(MouseClicked是事件的名稱) ....}註冊到事件:通過+=(Combine)註冊到事件,通過-=(Remove)取消註冊到事件。
private void MouseClicked(){..}//建構函式
Mouse.MouseClicked+=new MouseClickedEventHandler(MouseClicked//建構函式方法);
mouse.MouseClicked-=new MouseClickedEventHandler(MouseClicked);
觸發事件:檢查是否有註冊到這個事件上的用戶端(如果代表事件的欄位為空白,表示沒有用戶端),通過呼叫事件的委託來觸發事件。
if(MouseClicked!=null)MouseClicked();
此時觸發事件,通過呼叫事件的委託來處理事件何時使用委託,事件使用委託:當你需要c風格的函數指標;需要處理單一回調;回調時在方法調用或構造期間指定的,而不是通過add方法。使用事件:客戶通過add方法對回呼函數進行註冊;可能會有多個對對象對事件感興趣;希望終端使用者可以容易的在設計器中添加對事件的監聽。
繼承衍生類別:從基類繼承了欄位及方法,可以添加自己的欄位及方法。衍生類別以基類為基礎建立避免代碼的重複
class Person
{
string name;
int age;
public void Birthday()
{age++;}
}
class student :Person
{ int id;}
class Employee:Person
{ double salary;}
class Gradute:Student
{ string advisor;}
衍生類別的對象可以使用基類中的功能。
Student s = new Student()s.Birthday();
衍生類別只能有一個基類,不允許多繼承。衍生類別可以訪問基類中存取層級為protected的成員,其他類不可以。衍生類別的方法可以使用base關鍵字調用基類的方法。
class Person
{
public void Print()
{
Console.WriteLine(name);
Console.WriteLine(age);
}....}
class Student:Person
{
public new void Print()
{ base.Print();//
Console.WriteLine(id);
}...在衍生類別類中有與基類中的方法同名,有要調用基類中的方法此時base。
建構函式及繼承建立一個衍生類別的對象應對整個對象均進行初始化--首先是基類的部分,然後是衍生類別的部分。
衍生類別的建構函式應該調用基類的建構函式--在建構函式體之前使用:base()的文法;
--基類的
class Person
{
public Person(string name,int age)
{...}
...}
class Student:Person
{
int id;
public Student(string name,int age,int id):base(name,age)調用基類裡的建構函式並傳遞兩個參數,只有這樣才能初始化基類中的欄位。
{this.id =id;}
}
當基類建構函式為預設時可以不加base()。
定義虛方法衍生類別有時需要重寫基類的方法此時基類中的方法應定義為虛方法,使用virtual進行聲明。
class Token
{
public virtual string Name(){..}
}
衍生類別重寫裡的方法必須與基類裡的嚴格約束。
重寫使用override關鍵字。
class CommenToken:Token
{public override string Name(){}}
可以繼續對override方法進行重寫;
不能呢個講override方法聲明為static或private;
override方法不能更改virtual方法的訪問屬性。
隱藏繼承的成員:使用new關鍵字表示特意的隱藏可以隱藏虛方法及非虛方法。
class Person
{
int id;
public void SetId(int id)
{this.id = id;}
}
clss Student:Person
{
int id;
public new void SetId(int id)
{this.id =id;}
}
密封類不能作為基類,無法從密封類中派生(sealed)
抽象類別abstract抽象類別不能被執行個體化,但仍可使用其引用。包含抽象方法的類必須是抽象的。
多態
通過繼承,一個類可以用作多種類型:可以用作它自己的類型,任何基底類型,或者在實現介面時用作任何介面類型。這稱為多態。
基類的引用可以指向派生的對象
class Person
{
public string name;
public int age;...
}
class Employee:Person
{
public double salary;..
}
Employee e = new Employee();
Person p =new Employee();基類的引用可以指向派生的對象is-a 類型相容。引用的類型決定了允許的訪問--通過基類的引用只能訪問基類的成員。
Person p = new Employee();
p.name = "Bob";p.age = 23;p.salary = 42000.00//此時是不對的可以將衍生類別型的對象傳遞給基類引用的參數。
bool CheckAge(Person p)
{ return p.age>=21;}
有時候在繼承層次中會出現相同的方法--每個類可以提供各自獨立的版本,衍生類別中同名的方法可以隱藏掉基類中同名的方法,此時引用衍生類別中的方法。綁定:可以通過基類的引用調用方法。必須確定調用的是基類或是衍生類別的版本;確定的過程叫綁定。
void Evaluate(Employee e)//傳遞基類的參數
{ e.Promote();//基類中的同名方法}
Faculty f= new Faculty();//衍生類別執行個體化
Staff s = new Staff();
Evaluate(f);Evaluate(s);
靜態繫結:用了基類的方法。
動態綁定:virtual , override要看調用的參數是基類的還是衍生類別的,如果是基類的就調用基類的反之亦然。通過基類的引用只能訪問基類的成員,即使引用的是衍生類別的對象。使用new關鍵字
--衍生類別中的方法是隱藏了基類的方法;
--運行時方法的確定採用靜態繫結的方法;
--根據引用變數的類型確定使用的方法。
使用override關鍵字
--衍生類別中的方法是重寫了基類中的方法;
--運行時方法的確定採用動態綁定的方法;
--根據對象的類型確定使用的方法。
介面介面定義了一個規範也叫契約。使用關鍵字interface來建立介面。
介面可以包含方法,索引器,屬性,事件。但不允許包含實現,不允許包含其它類型的成員。
interface IMyInterface
{
void Process(int arg1,double arg2);
float this [int index]{get;set;}
string Name{get;set;}
event MouseEventHandler Mouse;
}
介面的成員的預設的存取層級為public不需要加public。類可以支援介面--聲明class:interface,必須實現介面的所有成員
(就是在類中必須有介面中成員方法的方法體的實現)。
若要實現介面成員,類中的對應成員必須是公用的,非靜態,並且與介面成員具有相同的名稱和簽名;實現的方法可以是虛的或非虛的;
類的屬性和索引器可以為介面上定義的屬性或索引器定義的額外的訪問器。介面引用可以指向實現介面的對象,訪問限制,只能提供者中定義的成員(介面和抽象類別都不能執行個體化)IFigter f = new Soldier();多個類可以實現同一個介面,可採用各自不同的方法實現介面。通過介面來編寫某個方法--此方法可以用於任何實現了介面的對象。類可以同時實現多個介面--通過逗號分隔,必須定義所有介面的方法。實現派生介面的類必須實現所有的方法--介面繼承層次上所有介面定義的方法。(類中要給出介面中所有成員的具體實現)。
字串ToString重寫
ToStringpublic class Person
{
string name;
int age;
public override String ToString()
{
return String.Concat(name,":"age.ToString());}
}
例子:
public class UserInfo
{
private string uName;
private int uAge;
pulic string UserName
{ get{return uName;} }
public int UserAge
{ get{return uAge;} }
public UserInfo(string umae,int uAge)
{ this.uName = uName; this.uAge=uAge;}
public override string ToString()
{
return string.Concat(uName,":",uAge);//return "你調用了我自己的ToString方法!"}
}
class Program
{
static void Main()
{
userInfo u = new UserInfo("Wangli",40):u.ToString();
Console.WriteLine(u.ToString());
}
數實值型別格式化字串:
C表示貨幣格式D表示十進位格式E表示科學計數法F表示定點格式P表示百分比格式X表示十六進位格式
DateTime.Now.DayOfWeek.Tostring("D")//返回枚舉類型
Console.WriteLine(DateTime.Now.Tostring());
複合格式化複合格式化支援構造的字串包含多個經過格式化的對象;
支援複合格式化的方法:String的靜態方法
Format,Consol.WriteLine,TextWrite.WriteLine(將輸出字串寫到流或檔案)
複合格式化:索引複合格式化中的格式字串使用大括弧中的數位識別碼可替換的參數
eg:
String MyString = String.Format("On{0},{2}yerars old.",Datetime.Now,"Tom",35);
Console.WriteLine(MyString);
複合格式化:格式可以在大括弧中添加格式資訊,來對最終的格式化輸出添加更多的控制:調用的時替換參數的類型實現的IFormattable介面中的ToString方法;如果未實現此介面則調用無參的ToString方法。
parseeg:
1.
string sNum = "58";
int iNum = int.Parse(sNum);
Console.WriteLine(iNum);
2.
推薦使用string sNum="58";int iNum;if((int.TryParse(sNum,out iNum)){
Console.WriteLine(iNum);}else{ Console.WriteLine("不是數字!!!");
}
字串基礎
String 類為方便使用,C#提供了string關鍵字作為System.String的同義字。String 是參考型別--使用new關鍵字建立。可將字元常量自動轉化為string對象(不用new)。
逸出序列:使用逸出字元/。
可以建立不進行轉義的字元常量:字串前加@string [email protected]”C:/windows/Config“;
String提供了唯讀Length屬性string s= "hello";
int i=s.Length;
String類型提供了唯讀索引器索引從零開始,文檔中對應的是chars數學,使用時應按照索引器的文法string s="hello";char c = s[4];s.ToUpper();
排序及反轉可以通過ToCharArray方法將字串的字元複製到字元數組中;
通過Array類中的Sort及Reverse方法可對其進行排序及反序。字串不變性沒有方法可以改變字串的內容,實際上是建立了代表新值的新的對象。StringBuilder代表了可變的字元序列。提供了改變其內容的方法。允許使用者對容量進行設定。
stringBuilder text=new stringBulider();
text.Append("dfd")text.Append()return text.ToString();
eg:
static void Main(string)
{
stringBulider text=new stringbulider();
for(int i=0;i<100;i++)
{
text.Append("字元"+i.ToString());
text.AppendFormat("{0}",i.TOstring());//
text.append(string.format("{0}",i.Tostring);
}
string Result=text.Tostring();}
}
Regex
Regex類建立RegexRegex方法--IsMatch方法,Replace方法模式比對Regex的強大不是體現在特定字元的匹配上,而是在字元類型的模式比對上
C#基礎總結 .