一、多態復習
使用個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; }
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();
static void Main() { int num=10; }
上面這段代碼,程序執行到Main放法系統就會開辟一個線程棧,這個線程棧用來存放這個方法執行的代碼,
程序一開始就會檢索方法裡面的所有變量,然後為int num開辟一個內存,系統會把這個內存裡面的數據清除 0x0000,
並且給這個內存空間一個地址(相當於給這個內存空間編了個號)。
值類型的變量直接存在線程棧中,其中的值也存在線程棧中。數據在聲明的時候系統就會根據聲明的類型開辟相應大小的內存空間。
3、引用類型
-》引用類型分為兩個空間來存儲,變量存儲在線程棧中,對象存儲在托管堆中
class Person() { } static void Main() { Person p=new Person(); }
二、對象的創建(new對象的時候其實在內存裡面做了很多事)
--》尋找類的繼承關系,從上往下計算所有的字段的字節數
--》再把這個數加上8個字節(如果是64位操作系統加16) (這裡8個字節方法棧4個指針占4個)
--》然後向操作系統申請空間
--》如果空間已滿,返回一個overflow異常
--》如果空間夠了就會返回該空間的首地址
--》根據計算出來的長度,會把這一片的內存空間清零
--》Nextobjptr會在原來的地址位置加上剛剛計算出來的數據,得到下一個對象的首地址
--》調用構造方法
多個對象在內存中時連續存儲的