-
1、泛型類(lèi)就是一個(gè)模子,放入類(lèi)型的材料(字段屬性方法),可以塑造出想要的產(chǎn)品。
2、語(yǔ)法
class Cage<T>//這是一個(gè)籠子類(lèi)和泛型類(lèi),類(lèi)名后加上一對(duì)<>,加上一個(gè)泛型參數(shù)
{
T[] petArray;//定義T類(lèi)型的數(shù)組
public void PutIn(T pet){···}//放入T類(lèi)型的寵物
public T TakeOut(int index){···}//占位符T,cage類(lèi)變?yōu)榫唧w類(lèi)時(shí),T相應(yīng)的變成具體數(shù)
}
//實(shí)例化
var dogCage=new Cage<Dog>();//得到狗狗籠子
var catCage=new Cage<Cat>();//得到貓咪籠子
3、為什么需要泛型,用基類(lèi)(包括所有類(lèi)的基類(lèi)object)或者公共的接口也可以實(shí)現(xiàn)一個(gè)Cage類(lèi),但是類(lèi)型太寬泛,需要顯示轉(zhuǎn)換類(lèi)型并判斷真是類(lèi)型是什么。
4、泛型使用:聲明一個(gè)泛型類(lèi)->引用泛型->構(gòu)造實(shí)例
class Cage<t>{···}
class Cage<Dog>{···}
dogCage=new Cage<Dog>;
比如不寫(xiě)Petcage<Dog> dog=new Petcage<Dog> ("名字");而用一個(gè)從來(lái)沒(méi)見(jiàn)過(guò)的 var代替。還有 return default<T>也沒(méi)解釋啥意思
理解:泛型就是在不確定類(lèi)的參數(shù)類(lèi)型和返回類(lèi)型時(shí),設(shè)置一個(gè)變量來(lái)代替這個(gè)固定的類(lèi)型。當(dāng)創(chuàng)建類(lèi)實(shí)例時(shí),在給這個(gè)變量賦對(duì)應(yīng)類(lèi)類(lèi)型值,這樣就可以實(shí)現(xiàn)一個(gè)類(lèi),輸出不同類(lèi)型的值和方法。
不用老師的例子,用一個(gè)給數(shù)組賦值輸出數(shù)組的例子更好理解;如設(shè)置一個(gè)類(lèi),構(gòu)造函數(shù)初始化一個(gè)數(shù)組數(shù)組類(lèi)型為int,有給數(shù)組賦值方法和獲取數(shù)組值的方法,在此注意:數(shù)組的類(lèi)型int和獲取數(shù)組值的方法的返回值類(lèi)型都為int,如果實(shí)例此類(lèi)調(diào)用方法,實(shí)參和返回值類(lèi)型也必須是int;就此限定死了此類(lèi)的實(shí)例; 如果想要一個(gè)設(shè)置char類(lèi)型的實(shí)例,還得必須創(chuàng)建一個(gè)新的char的類(lèi)和方法才能實(shí)現(xiàn);這樣代碼工作量很大;若使用泛型,用變量<T>代替固定類(lèi)型int或char,這樣在實(shí)例化的時(shí)候,將T賦不同類(lèi)型(int、double、char)就可以獲得想要的返回值類(lèi)型,從而實(shí)現(xiàn)了一個(gè)模板,只變一個(gè)參數(shù)T就能實(shí)現(xiàn)相同的功能
上面給出的例子。只需要把所有<T>去掉,后面的T全改為int或char 就能變?yōu)槠胀?lèi)了。對(duì)比理解非常簡(jiǎn)單了查看全部 -
1、什么是重載運(yùn)算符
不能創(chuàng)造新的運(yùn)算符,所以利用現(xiàn)有的某種運(yùn)算符,針對(duì)自定義類(lèi)或者結(jié)構(gòu)(預(yù)定義類(lèi)型和現(xiàn)有運(yùn)算符的運(yùn)算含義是確定的所有不能更改),定義某種運(yùn)算符(該運(yùn)算符和該操作具有一定相關(guān)性,如公狗狗+母狗狗=新生狗狗),從而簡(jiǎn)化自定義類(lèi)型的操作。
為什么需要重載運(yùn)算符:利用現(xiàn)有運(yùn)算符,簡(jiǎn)化自定義類(lèi)型的操作。最好是,該運(yùn)算符和該操作,具有一定億相關(guān)性。
2、語(yǔ)法細(xì)節(jié)
public static Dog operator +(Dog male,Dog female)//如公狗狗+母狗狗=新生狗狗
{
···
}
3、哪些運(yùn)算符可以重載
一元運(yùn)算符:+、-、!、~、++、- -、true、false(操作數(shù)必須是類(lèi)和結(jié)構(gòu))
二元運(yùn)算符:+、-、*、%、&、|!、^、<<、>>、= =、!=、>、<、>=、<=(兩個(gè)操作數(shù)至少有一個(gè)表示類(lèi)或者結(jié)構(gòu))
不能重載:=、&&、||、[](索引操作)、()等
4、重載運(yùn)算符不能做什么
創(chuàng)造新運(yùn)算符
改變運(yùn)算符語(yǔ)法
重定義運(yùn)算符如何處理預(yù)定義類(lèi)型
改變運(yùn)算符的優(yōu)先級(jí)和結(jié)合性
5、重在運(yùn)算符舉例
···
public void ShowAge()
{
Console.WriteLine("Age="+_age);
}
···
//重載自增操作,針對(duì)寵物的年齡
public static Pet opertor ++(Pet pet)//返回值為Pet類(lèi)型,參數(shù)為寵物自身。所有的重載方法都需要public static修飾
{
++pet._age;
return pet;
}
···
Dog dog=new Dog("Jack");
dog._age=2;
dog++;
dog.ShowAge();查看全部 -
隱式轉(zhuǎn)換語(yǔ)法public static implicit opertor Dog()(Cat cat){retuen new Cat(Dog dog);}
顯示轉(zhuǎn)換語(yǔ)法public static explicit operator Dog(Cat cat){...}
查看全部 -
1、裝箱:根據(jù)值類(lèi)型的值,在堆上創(chuàng)建一個(gè)完整的引用類(lèi)型對(duì)象,并返回對(duì)象的引用,是一種隱式轉(zhuǎn)換(語(yǔ)言自動(dòng)完成)。
2、為什么要裝箱
有時(shí)候需要將值類(lèi)型轉(zhuǎn)化為引用類(lèi)型(比如object)來(lái)進(jìn)行統(tǒng)一的操作(比如作為函數(shù)的參數(shù))和統(tǒng)一的存儲(chǔ)(比如object[])。
3、裝箱簡(jiǎn)單實(shí)例
int i=3;
object oi=null;
oi=i;//發(fā)生裝箱,原來(lái)的int保持不變,創(chuàng)建了一個(gè)新的對(duì)象,該對(duì)象在堆當(dāng)中。需要性能消耗的。
4、裝箱的本質(zhì)
就是在對(duì)上創(chuàng)建了一個(gè)引用類(lèi)型的副本,新創(chuàng)建的引用類(lèi)型和原來(lái)的值類(lèi)型相互獨(dú)立。
相互獨(dú)立代碼驗(yàn)證:
int i=3;
object oi=i;//發(fā)生裝箱
Console.WriteLine("i="+i+",oi="+oi.ToString);//輸出為i=3,oi=3
oi=10;
i=7;
Console.WriteLine("i="+i+",oi="+oi.ToString);//輸出為i=7,oi=10, oi存儲(chǔ)在堆中, i存儲(chǔ)在棧中
說(shuō)明兩者相互獨(dú)立
5、拆箱
將裝箱后的對(duì)象轉(zhuǎn)化回值類(lèi)型的過(guò)程,是一種顯示轉(zhuǎn)換(需要手動(dòng)干預(yù))。
6、拆箱實(shí)例
in i=3;
object oi=i;//裝箱
int j=(int)oi;//拆箱 通過(guò)強(qiáng)制轉(zhuǎn)換Console.WriteLine("j="+j);//輸出10
查看全部 -
1、靜態(tài)類(lèi)
包含靜態(tài)屬性和方法,被標(biāo)記為static
靜態(tài)類(lèi)不能創(chuàng)建實(shí)例,不能被繼承。
可以為靜態(tài)類(lèi)定義靜態(tài)構(gòu)造函數(shù)。
2、作用
主要用于基礎(chǔ)類(lèi)庫(kù)(math類(lèi))和擴(kuò)展方法。
3、如何擴(kuò)展方法
若有源代碼,直接添加一個(gè)新方法
如果不能修改單也不是密閉類(lèi),可以派生子類(lèi)擴(kuò)展
如果以上條件不滿足,可以使用靜態(tài)類(lèi)擴(kuò)展方法
3、在靜態(tài)類(lèi)中的靜態(tài)方法中參數(shù)中加入this關(guān)鍵,則可以直接利用對(duì)象調(diào)用方法就可以。static class PetGuide//擴(kuò)展Dog類(lèi)的方法
{?public?static double HowToFreedDog(this Dog dog){...}
{
Console.WriteLine("播放如何喂養(yǎng)一直狗狗的視頻");
}
}Dog dog=new Dog("Tommy");
dog.HowToFreedDog();
4、總結(jié)擴(kuò)展要求
擴(kuò)展方法所屬的類(lèi),必須是static類(lèi)
擴(kuò)展方法本身就是static方法
擴(kuò)展方法的第一個(gè)參數(shù)類(lèi)型,必須是this+類(lèi)名。
例如:
Dog類(lèi)沒(méi)辦法修改,修改Dog類(lèi)就需要擴(kuò)展方法,需要一個(gè)喂養(yǎng)寵物的方法
static class PetGuide//擴(kuò)展Dog類(lèi)的方法
{static public void HowToFreedDog(this Dog dog)
{
Console.WriteLine("播放如何喂養(yǎng)一直狗狗的視頻");
}
}
···
Dog dog=new Dog();//Dog類(lèi)中沒(méi)有HowToFreedDog();方法
dog.HowToFreedDog();//擴(kuò)展之后好像Dog類(lèi)中有這樣的方法一樣。查看全部 -
靜態(tài)類(lèi)和靜態(tài)成員
1、類(lèi)的靜態(tài)成員
成員被標(biāo)記為static時(shí),就是靜態(tài)成員。靜態(tài)成員將會(huì)被類(lèi)的所有實(shí)例共享,所有實(shí)例都訪問(wèn)統(tǒng)一內(nèi)存位置。
靜態(tài)成員跟實(shí)例成員分開(kāi)存放。靜態(tài)成員存放在堆中。class Dog{static int Num;}2、靜態(tài)成員訪問(wèn)
直接通過(guò)類(lèi)名訪問(wèn),普通成員需要通過(guò)實(shí)例訪問(wèn)。3、靜態(tài)成員聲明周期
獨(dú)立任何實(shí)例,沒(méi)有實(shí)例也可以訪問(wèn)。靜態(tài)成員使用之前編譯器已經(jīng)幫忙完成初始化。
4、靜態(tài)函數(shù)不能訪問(wèn)實(shí)例成員,僅能訪問(wèn)其他靜態(tài)成員,普通方法可以訪問(wèn)靜態(tài)成員
5、靜態(tài)構(gòu)造函數(shù)class Dog{static public void PrintNum(){Console.WriteLine(“Num=”+Num);}}用于初始化靜態(tài)字段
在引用任何靜態(tài)成員之前,和創(chuàng)建任何實(shí)例之前調(diào)用。
與類(lèi)同名,使用static,無(wú)參數(shù),沒(méi)有訪問(wèn)修飾符,普通構(gòu)造函數(shù)可以重載的.
靜態(tài)函數(shù)只能訪問(wèn)靜態(tài)成員,非靜態(tài)函數(shù)可以訪問(wèn)靜態(tài)/非靜態(tài)成員class?Dog//類(lèi)名
{static?Dog()//靜態(tài)構(gòu)造函數(shù),與類(lèi)同名,無(wú)參數(shù),無(wú)訪問(wèn)修飾符
{num=0;//只能訪問(wèn)靜態(tài)成員
}
}
查看全部 -
結(jié)構(gòu)和類(lèi)
1、不同點(diǎn)
結(jié)構(gòu)是值類(lèi)型(在棧中),類(lèi)是引用類(lèi)型(在堆中)
結(jié)構(gòu)不支持繼承,類(lèi)支持繼承
結(jié)構(gòu)不定義默認(rèn)構(gòu)造函數(shù),編譯器會(huì)定義
2、適用場(chǎng)合
結(jié)構(gòu)由于分配內(nèi)存快,作用域結(jié)束即被刪除。不需要垃圾回收,用于小型數(shù)據(jù)結(jié)構(gòu),傳遞過(guò)程會(huì)復(fù)制,應(yīng)該用ref類(lèi)參數(shù)傳遞提高效率。
類(lèi)用于其他需要繼承體系的場(chǎng)合。
例如:定義食物是一個(gè)不需要長(zhǎng)期存儲(chǔ)的數(shù)據(jù)類(lèi)型,吃完就沒(méi)有了,所以可以定義一個(gè)食物struct關(guān)于堆和棧內(nèi)存:? ? ? 棧內(nèi)存:棧內(nèi)存首先是一片內(nèi)存區(qū)域,存儲(chǔ)的都是局部變量,凡是定義在方法中的都是局部變量(方法外的是全局變量),for循環(huán)內(nèi)部定義的也是局部變量,是先加載函數(shù)才能進(jìn)行局部變量的定義,所以方法先進(jìn)棧,然后再定義變量,變量有自己的作用域,一旦離開(kāi)作用域,變量就會(huì)被釋放。棧內(nèi)存的更新速度很快,因?yàn)榫植孔兞康纳芷诙己芏獭? ? ?? 堆內(nèi)存:存儲(chǔ)的是數(shù)組和對(duì)象(其實(shí)數(shù)組就是對(duì)象),凡是new建立的都是在堆中,堆中存放的都是實(shí)體(對(duì)象),實(shí)體用于封裝數(shù)據(jù),而且是封裝多個(gè)(實(shí)體的多個(gè)屬性),如果一個(gè)數(shù)據(jù)消失,這個(gè)實(shí)體也沒(méi)有消失,還可以用,所以堆是不會(huì)隨時(shí)釋放的,但是棧不一樣,棧里存放的都是單個(gè)變量,變量被釋放了,那就沒(méi)有了。堆里的實(shí)體雖然不會(huì)被釋放,但是會(huì)被當(dāng)成垃圾,Java有垃圾回收機(jī)制不定時(shí)的收取。
查看全部 -
接口
1、接口就是制定一組函數(shù)成員,而不實(shí)現(xiàn)他們的引用類(lèi)型,用interface聲明。接口函數(shù)不能用其他訪問(wèn)修飾符修飾,默認(rèn)為public。interface ICatchMice{void CatchMice();}
2、接口只能用來(lái)被實(shí)現(xiàn)
例如? ?Cat:ICatchMice{ public void CatchMice(){...}
//實(shí)現(xiàn)接口函數(shù)
}Cat c=new Cat();
ICatchMice ic=(ICatchMice)c;
c.CatchMice(); //通過(guò)對(duì)象調(diào)用
ic.CatchMice(); //通過(guò)接口調(diào)用
3、一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口,當(dāng)一個(gè)類(lèi)同時(shí)繼承基類(lèi)和實(shí)現(xiàn)接口時(shí),應(yīng)該將基類(lèi)寫(xiě)在最前面,用逗號(hào)隔開(kāi)
可實(shí)現(xiàn)多個(gè)接口? ? ??
Cat:Pet ,ICatchMice,IClimbTree? ?//基類(lèi)? ? ? 接口1? ? ? ? 接口2
?{? ? ? ? ??
? ? ? ? ? ? public void CatchRat(){}.? ? ? ? ? ?
? ? ? ? ? ? ?public void ClimbTree()}
? ? ? ? ? ? ?...
}
4、一個(gè)類(lèi)實(shí)現(xiàn)接口時(shí),必須實(shí)現(xiàn)接口聲明的函數(shù)。
5、可以通過(guò)接口引用調(diào)用接口中的方法,也可通過(guò)實(shí)例調(diào)用接口方法。例子
爬樹(shù)為一個(gè)接口,抓老鼠為一個(gè)接口,當(dāng)貓這個(gè)類(lèi)實(shí)現(xiàn)這兩個(gè)接口時(shí),
Cat c=new Cat("tom");
爬樹(shù) ci=(爬樹(shù))c;
c.pashu();//通過(guò)實(shí)例調(diào)用接口方法
ci.pashu();//通過(guò)接口引用調(diào)用接口方法查看全部 -
密閉類(lèi) 密閉方法?
?sealed override public void Speak(){}
查看全部 -
派生類(lèi)調(diào)用基類(lèi)的構(gòu)造函數(shù)
查看全部 -
擴(kuò)展想擴(kuò)展類(lèi)的方法
查看全部 -
抽象
查看全部 -
依賴(lài)倒置原則,程序盡量依賴(lài)于抽象類(lèi)
查看全部 -
隱藏方法
查看全部 -
優(yōu)點(diǎn)
查看全部
舉報(bào)