程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 2、C#面向對象:封裝、繼承、多態、String、集合、文件(上),

2、C#面向對象:封裝、繼承、多態、String、集合、文件(上),

編輯:C#入門知識

2、C#面向對象:封裝、繼承、多態、String、集合、文件(上),


面向對象封裝

一、面向對象概念

面向過程:面向的是完成一件事情的過程,強調的是完成這件事情的動作。

面向對象:找個對象幫你完成這件事情。

二、面向對象封裝

把方法進行封裝,隱藏實現細節,外部直接調用。

打包,便於管理,為了解決大型項目的維護與管理。

三、什麼是類?

將相同的屬性和相同方法的對象進行封裝,抽象出 “類”,用來確定對象具有的屬性和方法。

類、對象關系:人是類,張三是人類的對象。

類是抽象的,對象是具體的。對象可以叫做類的實例,類是不站內存的,對象才占內存。

字段是類的狀態,方法是類執行的動作。

三個特性:封裝、繼承、多態。

四、訪問修飾符

public 公共的,任何地方都可以訪問

private 私有的,只有本類中成員可以訪問

protected 受保護的,可以在當前類以及子類訪問

Intelnal 只能在當前項目中訪問,在同一個項目中Intelnal和public權限是一樣的。

protected Intelnal 當前項目受保護的。

修飾類的訪問修飾符只有兩個:public、Intelnal

定義一個類時,如果不加訪問修飾符,默認是Intelnal

可訪問性不一致:子類可訪問性不能高於父類可訪問性,可能會被暴漏父類成員。

類中的成員,如果不加訪問修飾符,默認都是private

定義一個類

[public] class 類名
{
字段;
屬性;
方法;
}

class person
{
public string name; //字段
public int age;
public int height;
public void sayHi()
{
Console.WriteLine("Hello , my name is {0}, my age is {1} , my height is {2}" , this.name, this.age,this.height); //this當前類
}
}

使用關鍵字 new 創建類的對象稱之為實例化。

person p = new person();
p.name = "david";
p.age = 18;
p.height = 172;
p.sayHi();

五、屬性

用來限定字段的賦值和取值。

定義屬性

private int age;
public int Age{
set{
if(value < 0){ //賦值時進行判斷 可以不賦值
return;
}
this.age = value;
}
get { //取值
return this.age;
}
}

簡寫

public int age {set; get;} //3.0後新增 自動生成get set 代碼快。

六、靜態(static)

非靜態類

在非靜態類中,既可以有實例成員,也可以有靜態成員。

靜態類

在靜態類中,只能有靜態成員。

靜態類不可以用new實例化,直接用類名調用。

只有在程序全部結束之後,靜態類才會釋放資源。

靜態方法

在調用實例方法的時候,需要先實例化,再使用對象名.實例方法。person p = new person(); p.ss;

在調用靜態方法的時候,直接使用類名.靜態方法。person.ss;

不用new實例化 直接可用的方法 靜態(static)的方法。

static方法中可以調用其他satatic方法、字段、屬性,但是不能調用非static方法、字段、屬性。

在非static方法中可以調用static的方法、字段。

public static int age; //全局變量

七、構造函數

構造方法用來創建對象,並且初始化對象(對每個屬性依次賦值)。

定義構造方法時構造方法的名稱必須和類名相同, 沒有返回值 void也不用寫。

可以有參數,可以重載(多個參數不同的構造函數)。

如果不指定構造函數,則類默認有一個無參的構造函數,如果指定了構造函數,則不會再有默認的無參構造函數,需要自己來寫。

定義構造函數

class person{
public string name;
public person(string name){
this.Name = name;
}
}

通過構造函數初始化屬性

person hei = new person("小黑"); //此時p.name = "小黑";

八、this關鍵字

1、代表當前類中的對象。

2、在類當中顯示的調用本類的構造函數 :this

public person(string name; int age){ //全參構造函數
this.Name = name;
this.Age = age;
}
public person(string name):this("name",0){ //不執行方法體 去調用其他構造函數 有的寫上 沒有的寫個值
}

九、析構函數

//當程序結束的時候析構函數才執行,用來釋放資源。

 

~Student{
}

//GC可以自動釋放資源,但不是馬上,如果想馬上釋放資源則使用析構函數。

十、命名空間(namespace)

用來解決類重名問題

在其他的命名空間下使用這個命名空間時需要用using關鍵字引入該namespace。

using namespace;
namespace.class.person c = new namespace.class.person();

如果屬於同一命名空間下則不需要用using引入;

十一、對象的引用

值類型

int double datetime bool char struct enum等類型 賦值的時候是復制傳遞,第二個發生變化,第一個沒變化。

i = 10;j = i; i++; j //還是10

值類型存儲在內存的棧中。

引用類型

對象 string則是引用類型,類似快捷方式 倆個對象都指向原地址。

person p1 = new person(10); //構造函數賦值10 age person p2 = p1; p1.age++; //都11;

引用類型存儲在內存的堆中。

對象較大站內存,所以不會類似值類型那樣直接賦值一份,而是共同引用同一塊。

 

字符串String

一、字符串的不可變性

當給一個字符串重新賦值後,舊值依然存儲在內存中,並沒有被銷毀,而是重新開辟一塊內存空間存儲新的值。

當程序結束後,GC(垃圾回收)掃描整個內存,如果發現有的空間沒有被指向,則立即把他銷毀。

字符串可以看作是char類型的只讀數組

string s = "abcdefg";
s[0]; //可以通過數組下標的方式讀取0個 'a'值,只讀的不可以賦值。

如果想賦值

ToCharArray()

string s = "abcd"; //定義字符串
char[] ch = s.ToCharArray(); //ToCharArray()方法將字符串轉換為字符數組
ch[0] = 'b'; //修改字符數組的第一個值
s = new string(ch); //new string (char[]) 方法將字符數組轉換為字符串 內存還是新開了一個空間
Response.Write(s); //結果 "bbcd"; 更改了第一個字符

StringBuilder

每次改變值不用重新開辟內存

StringBuilder sb = new StringBuilder(); //定義StringBuilder;
sb.Append("insert "); //append 追加字符串
sb.Append(" values");

Stopwatch

用來測量程序運行時間

Stopwatch sw = new Stopwatch(); //定義
sw.Start(); //開始
//執行程序處
sw.Stop(); //結束
Response.Write(sw.Elapsed); //輸出運行事件

ToString()

將任意類型轉換為字符串; xxx.ToString();

Length

獲得字符串的長度 xxx.Length;

ToUpper()

將字符串轉換為大寫

ToLower()

將字符串轉換為小寫

Equals()

比較兩個字符串是否相等 s.Equals("s");

重載 s.Equals("s",StringComparison.OrdinalIgnoreCase) 第二個參數枚舉類型 可以忽略大小寫比較

Split()

將字符串按某字符進行分割,分割成字符串數組。

s.Split() 參數可字符,可字符數組,第二個參數,是否含有空白的字符數組

string s = "asdfljas;ld asljwo;ias fa sdl;fkw asdf"; 
char[] cs = { 'a', ' ', ';' }; // 需要去掉的字符
string[] sa = s.Split(cs, StringSplitOptions.RemoveEmptyEntries); // 字符串分割選項.刪除空白字符

Contains()

是否包含某字符 s.Contains("白大偉"); true false

Replace()

s.Replace("白大偉","*") 將包含白大偉的字符串全部替換為*

SubString()

從哪截到哪 s.SubString(0,20) 從0開始截 截到20

StartsWith()

判斷是否從某字符開始 s.StartsWith("a");

EndsWith()

判斷是否從某字符結束 s.EndsWith("g");

IndexOf()

查找字符串第一次出現的位置 s.IndexOf("a") 0 找不到返回-1

重載 s.IndexOf("a",2) 從2位置開始找

LastIndexOf()

查找字符串最後一次出現的位置 s.LastIndexOf("g");

Trim()

s.Trim(); //去掉字符串所有空格
s.TrimStart(); //去掉前面的空格
s.TrimEnd(); //去掉結尾空格

IsNullOrEmpty()

string.IsNullOrEmpty("s") 判斷該字符串是否為空或null

Join()

將字符串數組按照某字符進行鏈接,返回一個字符串 string.Join("|", "a","asdf","asdfasdf")  

 

面向對象繼承

一、繼承

將重復的一些成員,封裝到一個類中,作為這些類的父類。 解決代碼冗余

單根性:在c#中只允許繼承一個父類。

定義類時不指定繼承類,則默認繼承object類;object類是所有類的基類

定義類時用 : 號 繼承父類

子類繼承了父類的屬性和方法,但是子類無法繼承父類的私有字段。

子類沒有繼承父類的構造函數,但是子類會默認調用父類的無參構造函數,創建父類對象,讓子類可以使用父類中的成員

如果父類中有構造函數,需要寫一個無參的構造函數,在子類中顯示的調用父類的構造函數,使用關鍵字:base()

二、new 關鍵字

隱藏從父類集成的同名成員,隱藏後子類調用不到父類的成員。

當子類的成員和父類的成員名字相同的時候,可以使用new隱藏該成員,子類將調用不到父類中的該成員。

public new void ff(){
}

三、裡氏轉換

子類可以賦值給父類,如果父類中裝的是子類對象,那麼可以將這個父類強制轉換為子類對象。

class chinese:persion persion有的公共屬性方法子類有 子類還有自己的age 
{
public string age{get;set;}
}
chinese s = new chinese(); //初始化子類
persion p = s; //我要人 給我中國人 成立 
chinese c = p; //我要中國人 給我個人 不敢保證 報錯
if(p is chinese){
chinese china = (chinese)p; //強制轉換為中國人
}
object o = 3; //成立 object基類

四、類型轉換

is:如果能轉換成功,返回true。if(p is chinese)

as:如果能夠轉換,則返回對應的對象,否則返回null。chinese chin = p as Chinese;

  

 

集合

一、ArrayList集合

與數組區別:數組長度不可變,類型單一。集合長度可以改變,類型不固定。

1 •protected void Page_Load(object sender, EventArgs e) 2 { 3 ArrayList arry = new ArrayList(); 4 5 //添加單個 6 arry.Add(1); //int 7 8 arry.Add(3.14); //double 9 10 arry.Add("字符串"); //string 11 12 arry.Add('男'); //char 13 14 arry.Add(500m); //decimal 15 16 arry.Add(new int[] { 1, 2, 3, 4, 5 }); 17 18 arry.Add(new person()); 19 20 Random r = new Random(); //隨機數 21 22 r.Next(1, 9); // 1~8的隨機數 23 24 arry.Add(r); //添加集合 無需遍歷 25 26 arry.AddRange(new string[] { "one", "two", "three" }); //無需下面那樣遍歷也輸出值 27 28 //arry.AddRange(arry); 29 30 arry.Remove(500m); //刪除指定 31 32 arry.RemoveAt(0); //下標刪除 33 34 arry.RemoveRange(0, 1); //根據下標移除一定范圍的元素 35 36 //arry.Sort(); //升序排序 多元素報錯 37 38 arry.Reverse(); //反轉 倒序 39 40 arry.Insert(1, "插入的"); //指定位置插入元素 41 42 arry.InsertRange(1, new string[] { "asd", "asd" }); //指定位置插入集合 43 44 bool b = arry.Contains("插入的"); //判斷是否包含指定元素 45 //清空 46 //arry.Clear(); 47 48 //單個方法添加集合 遍歷 49 for (int i = 0; i < arry.Count; i++) // arry.Count; arry.Capacity; //可包含個數 實際個數 每次集合中實際包含的元素count超過了可包含的元素個數capcity的時候,集合就會向內存多申請一倍的空間,來保證集合的長度一直夠用。 50 { 51 if (arry[i] is person) //不判斷輸出命名空間 單個添加 52 { 53 Response.Write(((person)arry[i]).say()); 54 } 55 else if (arry[i] is int[]) 56 { 57 for (int j = 0; j < ((int[])arry[i]).Length; j++) 58 { 59 Response.Write(((int[])arry[i])[j]); 60 } 61 } 62 else 63 { 64 Response.Write(arry[i]); 65 } 66 } 67 } 68 69 class person 70 { 71 public string say() 72 { 73 return "Hello"; 74 } 75 } View Code

二、List<T>泛型集合

實現定義好類型,長度不限,省去判斷類型的操作

1 List<int> list = new List<int>(); //創建泛型集合ArryList 2 3 list.Add(1); //添加單個 4 5 list.Add(2); 6 7 list.Add(3); 8 9 list.Add(4); 10 11 list.Add(5); 12 13 list.Add(6); 14 15 list.AddRange(new int[] { 1, 2, 3, 4 }); //添加集合 16 17 //list.Clear(); //清空 18 19 if (list.Contains(2)) 20 { //是否存在 21 22 list.Remove(2); //刪除指定 23 24 list.RemoveAt(1); //刪除下標 25 26 list.RemoveRange(0, 1); //刪除范圍 27 } 28 29 var nums = list.ToArray(); //泛型集合轉換為數組 30 31 for (int i = 0; i < list.Count; i++) 32 { 33 Response.Write(list[i]); 34 } 35 36 for (int i = 0; i < nums.Length; i++) 37 { 38 Response.Write(nums[i]); 39 } 40 41 char[] chas = new char[] { 'a', 'b' }; 42 43 List<char> listc = chas.ToList(); //將數組轉換為泛型集合 44 45 for (int i = 0; i < listc.Count; i++) 46 { 47 Response.Write(listc[i]); 48 } View Code

三、var推斷類型

c#中的var和javascript中的var是不同的。

c#是強類型語言,必須對每一個變量的類型明確定義。如:int a= 1; char a = 'x';

js是若類型語言,var是用來聲明變量的。

在c#中var關鍵字是用來根據“值”自動推斷變量的類型,聲明時,必須賦初始值。 var a = 1; var b = 'x';

四、Hashtable鍵值對集合

通過鍵來查找對應值的,在鍵值對集合中,鍵必須是唯一的,值可以重復。

1 Hashtable hs = new Hashtable(); //創建 2 3 hs.Add(1, "字符串"); //添加第一種 4 5 hs.Add(2, '男'); 6 7 hs.Add(true, "正確的"); 8 9 hs.Add(false, "錯誤的"); 10 11 if (!hs.Contains(1)) //Contains == ContainsKey 是否包含key 12 { 13 hs.Add(1, "aaaa"); 14 } 15 16 if (hs.ContainsValue(1)) //是否包含值 17 { 18 hs.Add(7, "111"); 19 } 20 21 hs[5] = "asd"; //沒有新增 有替換 添加第二種 22 23 hs[1] = "賦值"; //賦值 通過hs[key] 24 25 //hs.Clear(); //清空 26 27 hs.Remove(2); //刪除key=2 28 29 foreach (var ht in hs.Keys) //foreach遍歷 從什麼中取 30 { 31 Response.Write(hs[ht]); 32 } View Code

五、Dictionary字典鍵值對集合

鍵值對集合,需要規范類型

1 Dictionary<int, string> dic = new Dictionary<int, string>(); //字典集合 規定鍵值對類型 2 3 dic.Add(1, "one"); //鍵必須唯一 4 5 dic.Add(2, "two"); 6 7 dic[1] = "new"; //存在覆蓋 不存在新增 8 9 foreach (var item in dic.Keys) 10 { 11 Response.Write("key:" + item + "---value:" + dic[item]); 12 } 13 14 foreach (KeyValuePair<int, string> kv in dic) 15 { 16 Response.Write("key:" + kv.Key + "---value:" + kv.Value); 17 } View Code

 

文件操作

一、Path類

用來獲得文件路徑的

1 string str = @"D:\video\xxx.avi"; 2 3 var fileNameExt = Path.GetFileName(str); //獲得文件名包含擴展名 4 5 var fileName = Path.GetFileNameWithoutExtension(str); //獲得文件名不包含擴展名 6 7 var fileExt = Path.GetExtension(str); //獲得文件擴展名 8 9 var DirectoryName = Path.GetDirectoryName(str); //獲得路徑包含文件夾名 10 11 var FullPath = Path.GetFullPath(str); //獲得文件全路徑 12 13 var combine = Path.Combine(@"c:\", "b.txt"); //連接兩個字符串作為路徑 14 15 Response.Write(fileNameExt + "<br />" + fileName + "<br />" + fileExt + "<br />" + DirectoryName + "<br />" + FullPath + "<br />" + combine); View Code

 

二、文件路徑

1、絕對路徑:在電腦的某磁盤存放的物理路徑。如:d:\game\sg7\sg7.exe

2、相對路徑:文件相對於程序的所在路徑。如:images/abc.jpg

三、編碼

因為計算機存儲數據存儲的是二進制,編碼就是將字符串以某種形式保存為二進制。

亂碼產生的原因,保存此文件時采用的編碼與打開時使用的編碼不符。

美國人編碼ASC 128 a~z 0~9

歐洲人編碼ASCII 256

中國人編碼GB2312 簡體字

香港、台灣人編碼Big5 繁體字

後來出的通用編碼unicode 解析慢

web通用編碼 utf-8

四、Encoding

Encoding.Default //默認編碼

Encoding cn = Encoding.GetEncoding("gb2312"); //獲得中文編碼

五、File類

用來操作文件的類

1 File.Delete(@"d:\11.txt"); //刪除一個文件 不經過回收站 2 if (!File.Exists(@"d:\11txt")) //判斷一個文件是否存在 3 { 4 File.Create(@"d:\11.txt"); //創建一個文件 5 } 6 File.Copy(@"d:\11.txt", @"d:\11_copy.txt"); //復制一個文件 7 File.Move(@"d:\11.txt", @"d:\11_copy.txt"); //移動一個文件 8 9 string write1 = "今天天氣不錯,空氣挺好的。"; 10 File.WriteAllBytes(@"d:11.txt", Encoding.Default.GetBytes(write1)); //轉換為字節數組後寫入 11 12 string[] write2 = new string[] { "明天天氣不好", "後天天氣也不好", "大後天也不好" }; 13 File.WriteAllLines(@"d:\11.txt", write2, Encoding.Default);//行寫入 14 15 string write3 = "麻煩,一次都寫入就好了。"; 16 File.WriteAllText(@"d:\11.txt", write3, Encoding.Default); //全部覆蓋寫入 17 18 //以字節數組形式讀取 19 byte[] buff = File.ReadAllBytes(@"d:\11.txt");//解碼 打開時 與保存時 編碼需要一致 20 Response.Write(Encoding.GetEncoding("GB2312").GetString(buff)); 21 22 //讀取指定編碼的文件的文本行 23 var strings = File.ReadLines(@"d:\11.txt", Encoding.Default); 24 foreach (var s in strings) 25 { 26 Response.Write(s + "<br />"); 27 } 28 29 //讀取指定編碼所有行 30 var str = File.ReadAllText(@"d:\11.txt", Encoding.Default); 31 Response.Write(str); View Code

ReadAllBytes字節讀取:讀取其他文件(多媒體,音樂,圖片等),時使用字節形式讀取。

ReadLines行讀取:讀取文本文件,具體操作某一行時,使用行讀取。

ReadAllText全讀取:讀取文本文件,不需要單行操作時,全部讀取。

六、文件流

File:讀取只適用於小文件,一次性讀取,很耗內存。

FileStream:操作大文件,讀取文件時一點一點的讀取。

FileStream操作字節的、StreamReader操作文本的。

1 //FileStream字節讀取數據 2 FileStream file1 = new FileStream(@"d:11.txt",FileMode.OpenOrCreate, FileAccess.ReadWrite); 3 4 byte[] by = new byte[1024 * 1024 * 5]; //限定讀取多少 5m 5 6 int result = file1.Read(by, 0, by.Length); //讀出來的放到by字節數組中,從0開始,讀到字節數組的長度結束。 返回實際讀取到的有效字節數。 7 8 string s = Encoding.Default.GetString(by, 0, result); //從多少開始解碼,解碼多少個 9 10 //關閉流 釋放所占的資源 GC不能自動回收 需要手動回收 11 12 file1.Close(); //使用using自動關閉 13 14 file1.Dispose(); //使用using自動釋放 15 16 Response.Write("該文件有:" + result / 1024 + "kb" + s); 17 18 19 20 //FileStream字節寫入數據 使用using 自動關閉/釋放資源 21 using (FileStream file2 = new FileStream(@"d:11.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)) 22 { 23 string str = "覆蓋字符串"; 24 byte[] byt = Encoding.Default.GetBytes(str); //轉換為字節數組 25 file2.Write(byt, 0, byt.Length); //要寫入的字符數組,從哪開始,到哪結束。 26 } 27 28 29 ////////////////////////////////////////////多媒體大文件copy 30 31 var source = @"D:\xxx.avi"; 32 33 var target = @"D:\new.avi"; 34 35 using (var fsread = new FileStream(source, FileMode.Open, FileAccess.Read)) //讀 36 { 37 using (var fswrite = new FileStream(target, FileMode.OpenOrCreate, FileAccess.Write)) //寫 38 { 39 while (true) 40 { 41 byte[] byread = new byte[1024 * 1024 * 5]; 42 43 int r = fsread.Read(byread, 0, byread.Length); 44 45 if (r == 0) //0則為全部讀取完畢 46 { 47 break; 48 } 49 fswrite.Write(byread, 0, r); //寫入 50 } 51 } 52 } 53 54 StreamRead、StreamWrite文本讀取、寫入 55 56 using (StreamReader sr = new StreamReader(@"d:\11.txt", Encoding.Default)) 57 { 58 while (!sr.EndOfStream) //是否讀到末尾 59 { 60 Response.Write(sr.ReadLine() + "<br />"); 61 } 62 } 63 64 using (StreamWriter sw = new StreamWriter(@"d:\121.txt", true))//寫入文件 true追加 false覆蓋 65 { 66 sw.Write("asdflkjasdlkfjalskdfjlakszxncv.mzxcv"); 67 } View Code

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved