面向對象封裝
一、面向對象概念
面向過程:面向的是完成一件事情的過程,強調的是完成這件事情的動作。
面向對象:找個對象幫你完成這件事情。
二、面向對象封裝
把方法進行封裝,隱藏實現細節,外部直接調用。
打包,便於管理,為了解決大型項目的維護與管理。
三、什麼是類?
將相同的屬性和相同方法的對象進行封裝,抽象出 “類”,用來確定對象具有的屬性和方法。
類、對象關系:人是類,張三是人類的對象。
類是抽象的,對象是具體的。對象可以叫做類的實例,類是不站內存的,對象才占內存。
字段是類的狀態,方法是類執行的動作。
三個特性:封裝、繼承、多態。
四、訪問修飾符
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集合
與數組區別:數組長度不可變,類型單一。集合長度可以改變,類型不固定。
二、List<T>泛型集合
實現定義好類型,長度不限,省去判斷類型的操作
三、var推斷類型
c#中的var和javascript中的var是不同的。
c#是強類型語言,必須對每一個變量的類型明確定義。如:int a= 1; char a = 'x';
js是若類型語言,var是用來聲明變量的。
在c#中var關鍵字是用來根據“值”自動推斷變量的類型,聲明時,必須賦初始值。 var a = 1; var b = 'x';
四、Hashtable鍵值對集合
通過鍵來查找對應值的,在鍵值對集合中,鍵必須是唯一的,值可以重復。
五、Dictionary字典鍵值對集合
鍵值對集合,需要規范類型
文件操作
一、Path類
用來獲得文件路徑的
二、文件路徑
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類
用來操作文件的類
ReadAllBytes字節讀取:讀取其他文件(多媒體,音樂,圖片等),時使用字節形式讀取。
ReadLines行讀取:讀取文本文件,具體操作某一行時,使用行讀取。
ReadAllText全讀取:讀取文本文件,不需要單行操作時,全部讀取。
六、文件流
File:讀取只適用於小文件,一次性讀取,很耗內存。
FileStream:操作大文件,讀取文件時一點一點的讀取。
FileStream操作字節的、StreamReader操作文本的。