一、多態復習
使用個new來實現,使用virtual與override
--》new隱藏父類方法 根據當前類型,電泳對應的方法(成員)
--》override重寫 無論什么情況,都是執行新的方法(成員)
繼承是實現多態的一個前提,沒有繼承多態是不能實現的
父類與子類實現多態
抽象類與子類實現
抽象類不能實例化
抽象類中的抽象方法沒有方法體
抽象類的成員有哪些
-》包含非抽象成員
-》不能實例化
-》子類必須實現父類的 抽象方法,除非子類也是抽象類
抽象成員有哪些呢?(凡是與方法有關的都可以抽象)
方法、屬性、索引、事件
自動屬性與抽象屬性
這個字段只需要實現讀和寫的功能不需要其他控制的時候就可以使用自動屬性
二、接口
1)接口的關鍵字:interface
2)接口的命名以I開頭
3)成員符沒有訪問修飾符
4)沒有方法實現體
5)接口里的成員必須是抽象的
6)接口定義能力即方法 派生類必須實現接口方法,除了抽象類
7)接口的存在就是為了實現多態
8)繼承可以解決繼承體積龐大的其問題,比如說有一個算法類里面有很多功能很齊全的計算方法,我現在要實現1+1=2的計算,此時如果調用這個功能齊全的類庫來實現,那么無疑使大材小用了
也會產生很多的冗余代碼,那么就可以考慮用接口來實現,接口的單一原則,接口實現的功能越少越好,一般一個接口實現一個功能,一般接口里面不要超過兩個方法
接口可以實現多繼承:
語法:
[public] [static] class 類名:[基類名,][[接口名,]接口名....]
接口比抽象類還抽象,接口是對功能的抽象
顯示實現接口:
-》為了避免接口的方法名相同
-》顯式實現接口必須由接口類型調用
顯示實現接口的方法不能一public修飾,方法名以接口名.方法名
interface IInterface1 { void Func(); } interface IInterface2 { void Func(); } class MyTest : IInterface1, IInterface2 { void IInterface1.Func() { Console.WriteLine("我是IInterface1提供的Func"); } void IInterface2.Func() { Console.WriteLine("我是IInterface2提供的Func"); } }
添加代碼段
三、值類型、引用類型
值類型就“復制文件”
-》值類型來源于Vluar Type
引用類型就是“復制快捷方式”
->引用類型來源于object
使用ref與out都可以將參數傳入方法,并保留在方法中對參數賦值時的影響
即參數在方法中被修改了,方法結束后,結果仍然保留方法中最后那一次被修改的值
ref reference 引用方法中用的是變量的引用,就是快捷方式
Out 參數用來輸出,即在方法中對變量的修改就是要傳到外邊輸出的
ref 在使用前要賦值
out 在方法中使用前要賦值
static void Main(string[] args){int num = 0;Func1(ref num);int num1;Func2(out num1);}static void Func1(ref int n){n = 10;}static void Func2(out int n){n = 10;}
三、靜態與非靜態
static修飾的成員就做靜態成員
靜態成員作用于整個應用程序
-》在程序里那里都可以調用它
如何定義靜態成員?
-》加static修飾
靜態成員與實例成員調用關系?
-》靜態方法、靜態類中不要允許直接調用靜態成員,如果要調用必須要new對象由對象來調用
如何調用靜態成員?
-》類名.成員名
靜態成員屬于整個類
實例成員屬于對象
當某個類的成員都是靜態成員不需要實例化的時候就可以把這個類定義成靜態類,在程序中重復使用
static與abstract級別相同
-》只能由其中一個修飾
與public和internal沒有關系
靜態類不允許繼承
靜態類里面不允許有實例成員
靜態構造方法
-》不允許帶參數
-》只允許由static修飾,沒有public修飾等
靜態構造方法從程序開始到結束只會被執行一次(一訪問這個類就會第一個執行靜態方法)
Dotnet基礎_異常處理篇
四、異常的處理
1)try-catch
2)try-catch-finally
3)tre-finally
try { //可能出現異常的額代碼 //打開數據庫,操作數據等 //一旦出現異常,就從異常處停下來跳到catch中,tyr中其后的代碼就不再執行了 } catch(Exception ex) { //一旦出現異常,就執行這里的代碼 //一般做日志等 } finally { // 釋放資源 }
異常向上拋,如果上面(調用者)沒有(catch)抓住,那么就會再向上面拋,如果上面一直都沒有抓住就會拋到系統去,系統就會檢索這個異常,給出解決方案
如果系統解決不了就會拋給微軟
不管拋異常或者return finally始終都會被執行,(可以用if判斷的錯誤盡量不要用try-catch)
三、GC 垃圾回收
垃圾回收總是從第0代開始回收
每次進行垃圾回收,前一代如果不使用了,就會被清掉,
如果,前一代中,某些對象仍然在使用中,就將其晉升為下一代。
如何自動的釋放資源
-》.net中對象有代的概念,每一個代是有內存范圍的
-》.net中的代有0、1、2三個等級
-》2代的內存最大
-》每次創建的對象默認為0代,當對象到達0代滿了的時候會自動觸動回收第0代
-》“回收”實際上就是將需要繼續使用的對象統一移動到另外一段連續的內存中
-》所有的地址指向都會發生變化(這個移動有時叫做壓縮)
-》如此操作,當第一代滿的時候就會調用回收第一代,并將需要使用的的對象放在第二代里
-》如此操作,第二代滿的時候,就會拋出一個overflow異常
當對象字節數大于85000,此時該對象將存儲在大對象托管堆中
在進行垃圾回收的時候,不去考慮大對象區的數據(除非大對象區的數據小于85000)
21250個int類型的對象==85000字節
// 16個
MyClass n1 = new MyClass();
MyClass n2 = new MyClass();
MyClass n3 = new MyClass();
MyClass n4 = new MyClass();
MyClass temp = n2;
n2 = null;
// 0x0012
// 手動調用垃圾回收器
System.GC.Collect(0);
// 會根據你當前系統中內存使用情況進行優化
n1 = null;
System.GC.Collect(0);
System.GC.Collect(1);
Console.ReadKey();
復習 值類型與引用類型
引用類型就是在處理地址
--》快捷方式與文件的關系
--》對象在內存中做了什么
32位的計算機用32個2進制位表示一個整數,同時使用32個二進制位來描述一個地址
1、內存空間的分配:分為3個空間
在棧空間中,系統是按高位到低位分配內存空間的(就是從大的數到小的數)
在堆空間中,系統是按低位到高位分配內存空間的(就是從小到大的數)
1)一個內存空間用來存放當前執行方法中的代碼
-》叫線程棧
-》一個方法一個線程棧
程序在一開始執行就會去檢索每個方法當中有哪些變量,并且為這些變量分配內存空間,相當于開辟好意見意見的空房間給這些房間編號(就是地址),
然后把內存里的數據清零(注意是清零相當于把里面的數據變成這樣 0x0000,所以程序并沒有執行到這個變量之前,光標放到這個變量上去會看到這個變量的值是 0,
但是此時的變量并不是賦值,并不可以用,因為這個0是內存空間里清除數據的0x0000,而不是賦值,等執行了等號之后才會真正地為這個變量賦值)
2)一個空間用來存放對象
-》托管堆
對象就是一個變量的值,比如說 int num=10; new person(); 這個10和new person();就是對象。
3)存放靜態對象,大對象(大于85000字節)等
2、值類型:
static void Main() { int num=10; }
上面這段代碼,程序執行到Main放法系統就會開辟一個線程棧,這個線程棧用來存放這個方法執行的代碼,
程序一開始就會檢索方法里面的所有變量,然后為int num開辟一個內存,系統會把這個內存里面的數據清除 0x0000,
并且給這個內存空間一個地址(相當于給這個內存空間編了個號)。
值類型的變量直接存在線程棧中,其中的值也存在線程棧中。數據在聲明的時候系統就會根據聲明的類型開辟相應大小的內存空間。
3、引用類型
-》引用類型分為兩個空間來存儲,變量存儲在線程棧中,對象存儲在托管堆中
class Person() { } static void Main() { Person p=new Person(); }
程序一開始在棧空間中開辟一個內存把里面的數據清零(0x0000),然后把這個p存到棧空間里去,當程序執行到main方法里面的時候會先執行new Person();(就是在new對象)
此時在就會在堆空間中開辟一個空間把數據清零,然后分配字段,,構造方法初始化,并產生一個地址,new對象時返回一個地址,這個地址指向了這個對象,然后執行等號賦值,此時賦值是把堆空間中這個對象產生的地址賦給變量p。此時變量P中存的是地址
我們處理的時候其實是對這個地址進行處理。
所以我們在傳參的是時候是把變量中的值復制一份傳過去,就是把這個地址復制了一份賦給方法中接收的變量,此時在方法中對這個變量是對地址的處理,所以會在外面保留影響
二、對象的創建(new對象的時候其實在內存里面做了很多事)
--》尋找類的繼承關系,從上往下計算所有的字段的字節數
--》再把這個數加上8個字節(如果是64位操作系統加16) (這里8個字節方法棧4個指針占4個)
--》然后向操作系統申請空間
--》如果空間已滿,返回一個overflow異常
--》如果空間夠了就會返回該空間的首地址
--》根據計算出來的長度,會把這一片的內存空間清零
--》Nextobjptr會在原來的地址位置加上剛剛計算出來的數據,得到下一個對象的首地址
--》調用構造方法
多個對象在內存中時連續存儲的
新聞熱點
疑難解答