1. 程式人生 > >C#基礎筆記(四)

C#基礎筆記(四)

1.欄位、屬性、方法、建構函式
欄位:儲存資料
屬性:保護欄位,對欄位的取值和設值進行限定
方法:描述物件的行為
建構函式:初始化物件(給物件的每個屬性依次的賦值)
類中成員,如果不加訪問修飾符,預設都是private()
private
給每一個私有的欄位都配備一個公有的屬性
屬性的本質就是兩個方法

當我們建立好物件後
給這個物件的屬性賦值用set
列印這個屬性的值的時候執行get

this:當前類的物件
this:呼叫當前類
this是把屬性和區域性變數區分開來的。
建構函式:1、沒有返回值 連void也沒有
2、建構函式的名稱跟類名一樣

建構函式可以過載
:this(name,0,0,gender)

new:1、在記憶體中開闢一塊空間
2、在開闢的空間建立物件
3、呼叫物件的建構函式

限定:set get 建構函式

靜態方法 類名.方法名
例項方法 物件名.方法名

靜態方法只能訪問到靜態成員
靜態類不能建立物件

2、名稱空間
名稱空間可以看做是類的資料夾
可以認為類是屬於名稱空間的。
如果在當前專案中沒有這個類的名稱空間,需要我們手動的匯入這個類所在的
名稱空間。
1)、用滑鼠去點
2)、alt+shift+F10
3)、記住名稱空間,手動的去引用

3、在一個專案中引用另一個專案的類
1)、在解決方案資源管理器的引用右鍵新增引用
2)、引用名稱空間

3、值型別和引用型別
區別:
1、值型別和引用型別在記憶體上儲存的地方不一樣。
2、在傳遞值型別和傳遞引用型別的時候,傳遞的方式不一樣。
值型別我們稱之為值傳遞,引用型別我們稱之為引用傳遞。
我們學的值型別和引用型別:
值型別:int、double、bool、char、decimal、struct、enum
引用型別:string、自定義類、陣列
儲存:
值型別的值是儲存在記憶體的棧當中。
引用型別的值是儲存在記憶體的堆中。

堆、棧、靜態儲存區域
4、堆和棧的區別 (靜態區 )
http://blog.csdn.net/caozhenyu/article/details/9297605 csdn 介紹的比較詳細

int number=10; 在棧中開闢一個空間,在這個空間儲存10,給這個空間起名叫number
string s=“123”; 在堆中開闢一個空間,在這個空間儲存"123",有一個地址(引用) 0x001001,
在棧中開闢一個空間,存堆中的地址0x001001,起名叫s。現在s是指向堆中的記憶體的

Person zsPerson=new Person();
zsPerson.Name=“張三”;

在堆中開闢空間,在這個空間儲存 new Person(); “張三”,有一個地址(引用)
在棧中開闢一個空間,存堆中的地址,起名叫zsPerson

4、字串
1)、字串的不可變性
當你給一個字串重新賦值之後,老值並沒有銷燬,而是重新開闢一塊空間儲存新值。
當程式結束後,GC掃描整個記憶體,如果發現有的空間沒有被指向,則立即把它銷燬。

int 重新賦值 會在原來的棧空間覆蓋原值
string 重新賦值,會在原來的堆空間重新開闢一個空間存新值。棧中存地址的空間不變

建立 string s1=“張三”
string s2=“張三”
只在堆中開闢一塊空間 儲存"張三"
在棧中開闢兩塊空間命名為s1和s2指向堆中的空間(儲存堆中的地址)

個人解釋:

①當你建立了S1和S2後,就會在棧中開闢兩個空間

一個叫S1,記憶體地址是1000XX

一個叫S2,記憶體地址是2000XX

②你給S1,S2賦值的string 型別 “張三”

是存在堆中開闢的空間內

它也有個記憶體地址是XX0001

③你棧中的S1,S2空間存的是堆中 的記憶體地址XX0001,他們是同一個東西

④如果你再 S1=“李四”

                S2=“李四”

它們也只是把S1,S2裡面的記憶體地址指向堆中開闢的一個叫"李四"的空間的記憶體地址。

原來堆中存的"張三"不會有任何改變。

⑤當你清理記憶體的時候,那個"張三"因為記憶體地址沒有被引用過,就會被清理掉(垃圾回收)

視窗-即時-及時視窗-&s1 &s2 可以看s1和s2的記憶體地址 上面是棧中的地址,下面是堆中的地址

2)、我們可以把字串看做是char型別的一個只讀陣列。
ToCharArray();將字串轉換為char陣列
new string(char[] chs):能夠將char陣列轉換為字串

複製程式碼
1 string s = “abcdefg”;
2 char[] chs = s.ToCharArray();
3 chs[0] = ‘b’;
4 s= new string(chs);
5 Console.WriteLine(s);
6 Console.ReadKey();
複製程式碼
Stopwatch 計時器
Stopwatch sw=new Stopwatch();
sw.Start();開始計時
sw.Stop();停止計時
sw.elapsed 當前例項測量得出的總執行時間

StringBuilder sb=new StringBuilder();

sb.Append(i);追加

能把這個i累加到sb裡面

複製程式碼
1 StringBuilder sb = new StringBuilder();
2 //string str = null;
3 Stopwatch sw = new Stopwatch();
4 sw.Start();
5 for (int i = 0; i < 100000; i++)
6 {
7 //str += i;
8 sb.Append(i);
9 }
10 sw.Stop();
11 Console.WriteLine(sw.Elapsed);
12 Console.ReadKey();
複製程式碼

string 為什麼這麼慢,因為它每次都要開空間
stringbuilder這麼快是因為它在記憶體中開空間,用來用去都是同一塊型別。
最後stringbuild還是得要tostring轉為string 型別。

5、字串提供的各種方法
//把字串轉為大寫
LessonOne =LessonOne.ToUpper();
//把字串轉為小寫
LessonOne=LessonOne.ToLower();
//比較兩個字串的值
LessonOne.Equals(LessonTwo,StringComparison.OrdinalIgnoreCase)
Equals同樣 StringComparison.OrdinalIgnoreCase 列舉.忽略被比較的字串的大小寫

string s = “a b c 3 12 - + _ , == fdf”;
//分割字串Split
//把不想要的字元都寫在char數組裡
//陣列雖然幹掉了,但是還是留了一個空""
//後面加上,StringSplitOptions.RemoveEmptyEntries把空給幹掉
char[] chs = { ’ ‘,’_’,’=’,’+’,’,’,’-’};
string[] str = s.Split(chs,StringSplitOptions.RemoveEmptyEntries);
Console.ReadKey();

練習

複製程式碼
Console.WriteLine(“請輸入日期,格式如2008-08-08”);
string s = Console.ReadLine();
//可以不用建立char []chs,直接把它New在裡面
string [] date= s.Split(new char [] {’-’ },StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(“你輸入的日期是{0}年{1}月{2}日”,date[0],date[1],date[2]);
Console.ReadKey();
複製程式碼
//contains(包括),判斷字串中是否包含指定的字串

//Replace(替換) 將字串中某個字串替換成一個新的字串,返回
練習

複製程式碼
1 string str = “國家領導人老趙”;
2 if(str.Contains(“老趙”))
3 {
4 str=str.Replace(“老趙”,"**");
5 }
6 Console.WriteLine(str);
7 Console.ReadKey();
複製程式碼
複製程式碼
1 //Substring 擷取字串
2 string str = “今天天氣好晴朗,處處好風光”;
3 //把字串當做陣列,從下標0開始擷取
4 str = str.Substring(1);
5 //從“天”開始擷取,擷取2個字
6 str = str.Substring(1,2);
7 Console.WriteLine(str);
8 Console.ReadKey();
複製程式碼
複製程式碼
1 //StartsWith()判斷字串中是否以子串value開始
2 //EndsWith()判斷字串中是否以子串value結束
3 //使用方式相同
4 string str = “今天天氣好晴朗,處處好風光”;
5 if(str.StartsWith(“今天”))
6 {
7 Console.WriteLine(“是的”);
8 }
9 else
10 {
11 Console.WriteLine(“不是”);
12 }
13 Console.ReadKey();
複製程式碼
複製程式碼
1 //判斷某個字串在字串中第一次出現的下標位置,如果沒有返回-1,由int型別接受
2 string str = “今天天氣好晴朗,處處好風光”;
3 int n=str.IndexOf(‘天’);
4 //後面加個Int型別數字,表示找字串中的第幾個‘天’的下標
5 //int n=str.IndexOf(‘天’,2);
6 //如果要找到所有‘天’的下標,就需要用迴圈來找
7 Console.WriteLine(n);
8 Console.ReadKey();
複製程式碼
1 //LastIndexOf():判斷某個字串在字串中最後一次出現的位置,如果沒有同樣返回-1
2 //LastIndexOf()經常和Substring配合使用
3 string path = @“c:\a\b\c\d\e\f\g\ff\蒼\ds\fgd\d\蒼老師.wav”;
4 //找最後一個斜線後出現的文字才是最準確的,一直截到最後
5 int index=path.LastIndexOf("\"); 兩個斜線表示一個斜線
練習

1 string path = @“c:\a\b\c\d\e\f\g\ff\蒼\ds\fgd\d\蒼老師.wav”; @代表字串中的\都表示
2 int index = path.LastIndexOf("\");字串中\代表一個
3 path=path.Substring(index+1); 擷取是從\開始,所以要加1
4 Console.WriteLine(path);
5 Console.ReadKey();
複製程式碼
1 //Trim():去掉字串中前後的空格
2 //TrimEnd():去掉字串中結尾的空格
3 //TrimStart():去掉字串中前面的空格
4 string str = " hahaha “;
5 str=str.Trim();
6 Console.Write(str);
7 Console.ReadKey();
複製程式碼
複製程式碼
1 //string.IsNullOrEmpty():判斷一個字串是否為空或者為null
2 string str = null;
3 if(string.IsNullOrEmpty(str))
4 {
5 Console.WriteLine(“是的”);
6 }
7 else
8 {
9 Console.WriteLine(“不是”);
10 }
11 Console.ReadKey();
複製程式碼
1 //string.Join():將陣列按照指定的字串連線,返回一個字串。
2 string[] name = { “張三”,“李四”,“王五”,“趙六”,“田七” };
3 string str=string.Join(”|", name); params可變引數:可以放陣列也可以放參數
4 Console.WriteLine(str);
5 Console.ReadKey();
1)、Length:獲得當前字串中字元的個數
2)、ToUpper():將字元轉換成大寫形式
3)、ToLower():將字串轉換成小寫形式
4)、Equals(lessonTwo,StringComparison.OrdinalIgnoreCase):比較兩個字串,可以忽略大小寫
5)、Split():分割字串,返回字串型別的陣列。
6)、Substring():擷取字串。在擷取的時候包含要擷取的那個位置。
7)、IndexOf():判斷某個字串在字串中第一次出現的位置,如果沒有返回-1、值型別和引用型別在記憶體上儲存的地方不一樣。
8)、LastIndexOf():判斷某個字串在字串中最後一次出現的位置,如果沒有同樣返回-1
9)、StartsWith():判斷以…開始 bool型別判斷
10)、EndsWith():判斷以…結束 bool型別判斷
11)、Replace():將字串中某個字串替換成一個新的字串
12)、Contains():判斷某個字串是否包含指定的字串 bool型別判斷
13)、Trim():去掉字串中前後的空格
14)、TrimEnd():去掉字串中結尾的空格
15)、TrimStart():去掉字串中前面的空格
16)、string.IsNullOrEmpty():判斷一個字串是否為空或者為null
17)、string.Join():將陣列按照指定的字串連線,返回一個字串。

6.複習
字串需要掌握的亮點
1)字串不可變,每新建一個字串都會在記憶體中開闢一塊新的空間
2)字串的方法

StringBuilder和String的區別
String在進行運算時(如賦值、拼接等)會產生一個新的例項,而StringBuilder則不會。
使用StringBuilder進行操作,最後再用ToString轉為String型別即可。

1 string path = @“C:\Users\SJD\Desktop\22.txt”; 路徑
2 string [] str= File.ReadAllLines(path,Encoding.Default);
3 //File(靜態類).ReadAllLines(方法,讀取所有的行)讀取的全是亂碼
4 //Encoding.Default 去除亂碼
5 Console.ReadKey();
7.練習
char型別陣列轉為string型別

1 char[]chs={‘1’,‘2’,‘3’};
2 string str=new string(chs);
求出字串中所有出現的e的位置
@第一種方法(必須會)

複製程式碼
1 string str = “daghdewejhadgwehhjfhajejwwe”;
2 int index = str.IndexOf(‘e’);
3 Console.WriteLine(“第1次出現e的位置是{0}”, index);
4 int count = 1;
5 while (index != -1)
6 {
7 index = str.IndexOf(‘e’, index + 1);
8 count += 1;
9 if (index == -1)
10 {
11 break;
12 }
13 Console.WriteLine(“第{0}次出現e的位置是{1}”, count, index);
14 }
15 Console.ReadKey();
複製程式碼
第二種方法
查詢多個字的話就不行

複製程式碼
1 string str = “daghdewejhadgwehhjfhajejwwe”;
2 for (int i = 0; i < str.Length; i++)
3 {
4 if(str[i]==‘e’)
5 {
6 Console.WriteLine(i);
7 }
8 }
9 Console.ReadKey();
複製程式碼
8.繼承
每一個類都要單獨寫在一個類檔案裡。

我們可能會在一些類中,寫一些重複的成員,我們可以將這些重複的成員,
單獨的封裝到一個類中,作為這些類的父類。

格式 子類:父類
Student、Teacher、Driver 子類 派生類
Person 父類 基類

子類繼承了父類,那麼子類從父類那裡繼承過來了什麼?
首先,子類繼承了父類的屬性和方法,但是子類並沒有繼承父類的私有欄位。能看到也不能用
李一個有錢親戚掛了,受益人是李,但是沒有給他銀行密碼。他繼承過來了卻用不了。
問題:子類有沒有繼承父類的建構函式?
答:子類並沒有繼承父類的建構函式,但是。子類會預設的呼叫父類無引數的建構函式,
建立父類物件,讓子類可以使用父類中的成員。
所以,如果在父類中重新寫了一個有引數的建構函式之後,那個無引數的就被幹掉了,
子類就呼叫不到了,所以子類會報錯。

執行完父類無參建構函式,再去執行子類的
執行父類的建構函式,就相當於建立一個父類的物件
因為沒有父類的物件,子類沒辦法用父類的屬性
建立子類物件的時候,也順便建立了他父類的物件,這樣才能用到父類的屬性和方法,成員
子類包含了自己的屬性和父類物件(建構函式),內部的父類又包含了他的屬性和方法

繼承建構函式的過程可以加入子類的屬性

父類預設呼叫無參的而不是有參的
解決辦法:
1)、在父類中重新寫一個無引數的建構函式。
2)、在子類中顯示的呼叫父類的建構函式,使用關鍵字:base()

9.繼承的特性
1、繼承的單根性:一個子類只能有一個父類。
2、繼承的傳遞性:爺爺-爸爸-兒子-孫子

10.檢視類圖
右鍵類檔案-檢視-檢視類圖 可以看類之間的繼承關係

11.object是所有類的基類。
如果沒有讓一個類繼承於另外一個類,那麼這個類就繼承於object

12.new關鍵字
1)、建立物件
2)、隱藏從父類那裡繼承過來的同名成員。
隱藏的後果就是子類呼叫不到父類的成員。

子類成員名稱和父類成員名稱相同,會隱藏繼承的父類成員,隱藏後果就是調不到了。
新增new後只是不報錯

13.複習
值型別
引用型別
字串 不可變性
一坨方法
StringBuilder
繼承 單根性
傳遞性
子類跟父類建構函式的關係
子類繼承了父類的什麼?
new關鍵字