.NET 基礎 一步步 一幕幕[面向對象之new、this關鍵字]

常常會有人問:小夥子,有沒有對象啊,要不要大叔我幫你介紹一個啊,小夥子會說:大叔,不用我本身new一個就行了。(PS:活該你沒有對象)程序員

上邊固然是一個段子咯,程序員那會沒有對象,本身new一個就有了啊。好了進入今天的主題 new和this的關鍵字。ide

new關鍵字函數

new 關鍵字可用做運算符、修飾符或約束三種用法:測試

1) new 運算符:用於建立對象和調用構造函數。this

a)   Person person = new Person();//new是一個運算符
(1)在內存中開闢一塊合適大小的空間
(2)在這個空間裏建立對象
(3)調用這個對象的構造函數
(4)返回這個空間的引用地址spa

代碼展現:對象

class Program
    {
        static void Main(string[] args)
        {
            Reporter rep = new Reporter("記者", 11, '男', "偷拍");
            rep.SayHello();
            rep.Test();
            Console.ReadKey();
        }
    }

    public class Person
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        private int _age;
        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }
        private char _gender;
        public char Gender
        {
            get { return _gender; }
            set { _gender = value; }
        }


        public Person(string name, int age, char gender)
        {
            this.Name = name;
            this.Age = age;
            this.Gender = gender;
        }

        public void Test()
        {
            Console.WriteLine("測試");
        }

        public void SayHello()
        {
            Console.WriteLine("你們好,我是人類");
        }
    }


    public class Reporter : Person
    {
        public Reporter(string name, int age, char gender, string hobby)
            : base(name, age, gender)
        {
            this.Hobby = hobby;
        }


        private string _hobby;

        public string Hobby
        {
            get { return _hobby; }
            set { _hobby = value; }
        }

        public void ReporterSayHello()
        {
            Console.WriteLine("我叫{0},我是一名狗仔,個人愛好是{1},我是{2}生,我今年{3}歲了", this.Name, this.Hobby, this.Gender, this.Age);
        }


        public new void SayHello()
        {
            Console.WriteLine("你們好,我是記者");
        }
    }

  

2) new 修飾符:在用做修飾符時,new 關鍵字能夠顯式隱藏從基類繼承的成員。blog

代碼展現:繼承

public class BaseClass
    {
        public void functionA()
        {
            Console.WriteLine("BaseFunctionA http://www.cnblogs.com/sosoft/");
        }
        public virtual void functionB()
        {
            Console.WriteLine("BaseFunctionB http://www.cnblogs.com/sosoft/");
        }
    }
   public class DerivedClass:BaseClass
    {
        public new void functionA()
        {
            Console.WriteLine("DerivedFunctionA http://www.cnblogs.com/sosoft/");
        }
        public override void functionB()
        {
            Console.WriteLine("DerivedFunctionB http://www.cnblogs.com/sosoft/");
        }
    }

調用:
BaseClass baseFunction=new DerivedClass();
baseFunction.functionA();
baseFunction.functionB();

運行結果:索引

 BaseFunctionA http://www.cnblogs.com/sosoft/

 DerivedFunctionB http://www.cnblogs.com/sosoft/

new是隱藏基類方法,override是覆寫基類方法。若是要訪問new隱藏了的基類成員須要使用base關鍵字實現。

隱藏和重寫基類方法的異同:

1:方法重寫:就是在基類中的方法用virtual關鍵字來標識,而後在繼承類中對該類進行重寫(override),這樣類中的方法已經被重寫了,已經失去了功能了。當讓基類的對象的引用直接指向繼承類的對象時(多態性),調用該方法則是調用的繼承類的方法。

2:方法隱藏:不管基類中的方法是否用了virtual關鍵字,繼承類中均可以用new關鍵字(若是不用new的話,不會產生錯誤,但會生成一個編譯警告)將基類中的方法隱藏,所謂隱藏就是隱藏,不像重寫,重寫就是原來的(基類中)已經不存在了,而隱藏是原來的還存在。因此當讓基類的對象的引用直接指向繼承類的對象時(多態性),調用該方法則是調用的基類的方法。

 

3new 約束:用於在泛型聲明中約束可能用做類型參數的參數的類型。 

代碼展現:

class Person<T> where T : new()
    {
        public T GetName()
        {
            return new T();
        }
    }

    class Boy
    {
        private string _name;

        public string Name
        {
            get{return _name;}
            set { _name = value; }
        }

        public Boy()
        {
            _name = "feng";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Person<Boy> MBoy = new Person<Boy>();

            Boy a = new Boy();
            Console.WriteLine(a.Name);

            Console.WriteLine(MBoy.GetName().Name);
            Console.ReadKey();
        }
}

運行結果:

打印出2個"feng"

4) new 實現多態

a)  好比經過基類擴展來實現繼承式多態.

b)  經過繼承接口來實現多態.

代碼展現:

class Num
    {
        public static int i = 111;

        public virtual void ShowClassInfo()
        {
            Console.WriteLine("我是基類呵呵");
        }
        public virtual void ShowNum()
        {
            Console.WriteLine("基類的數字是{0}", i.ToString());
        }
    }

    class SubNum : Num
    {
        new public static int i = 222;

        //new 做爲修飾符:只是隱藏基類同名方法
        public new virtual void ShowClassInfo()
        {
            Console.WriteLine("我是子類哈哈");
        }

        //override則是覆寫了基類的方法
        public override void ShowNum()
        {
            Console.WriteLine("子類的數字是{0}", i.ToString());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Num num1 = new Num();//new 運算符用法
            num1.ShowNum();
            SubNum sbnum = new SubNum();
            //下面2個調用的都是子類的方法 可是實現機制不同
            sbnum.ShowNum();//結果:222

            sbnum.ShowClassInfo();//結果:我是子類哈哈
            
            //new做爲多態的用法:下面是典型的基類繼承似多態
            Num num2 = new SubNum();//num2雖然是基類的變量,可是指向了之類SubNum實例的引用

            //調用方法時會在運行期檢查虛擬方法表,來肯定要調用的方法
            num2.ShowClassInfo();//因爲方法只是被隱藏了,沒有被重寫 全部仍是調用的基類的方法 //結果:我是子類呵呵

            num2.ShowNum();//方法被覆蓋了 全部調用的是子類的方法 //結果: 222
            Console.ReadKey();
        }
    }

注意:前方高能:

new關鍵字在咱們的程序中可謂是無時不刻在用到,那麼new關鍵字均可以用在哪些地方呢?考慮如下幾個問題:
一、new一個class對象和new一個struct或者new一個enum有什麼不一樣?
  答:new一個class時,new完成2個內容:一是調用newobj命令爲實例在託管堆中分配內存,二是調用構造函數實現對象初始化。
  new一個struct時,new運算符用於調用其構造函數,完成實例的初始化。
二、new在.NET中除了建立對象實例外,還能夠作什麼?   答:new關鍵字:做爲運算符能夠建立對象和調用構造函數;   做爲修飾符能夠用於向基類成員隱藏繼承成員,實現派生類中隱藏基類的virtual方法,不能和override共存;   做爲約束能夠在泛型聲明中約束可能用做類型參數的參數類型,即new約束指定泛型類聲明中的任何類型參數都必需要有公共的無參構造函數;   使用new關鍵字實現多態。
三、new運算符能夠重載嗎?   答:new運算符不能夠重載。
四、泛型中new關鍵字的做用?   答:new運算符用於返回一個引用,指向系統分配的託管堆的內存地址,new分配內存失敗,將引起OutOfMemoryException異常。
五、new一個繼承下來的方法和override有什麼區別?   答:new是隱藏基類方法,override是覆寫基類方法。若是要訪問new隱藏了的基類成員須要使用base關鍵字實現。
六、int i和int i = new int()有什麼不一樣?   答:new一個int時,new運算符用於初始化其值爲0,使構造函數完成更優越的初始化操做。

 

this關鍵字

1)、表明當前類的對象

代碼展現:

class MyClass
    {
        // 聲明一個名爲"myVal"的整型字段
       public int myVal = 10;

        // 聲明一個構造函數,該函數帶一個名爲"myVal"的參數
        public MyClass(int myVal)
        {
            // "this"表示MyClass類的當前實例
            // 在這裏經過this能夠在語義上區分紅員名myVal和參數名myVal
            this.myVal += myVal;

            // 使用this做爲當前對象的實參傳遞給Compute方法
            int res = myVal + MyClass1.Compute(this);
        }
    }

  

2)、在類當中顯示的調用本類的構造函數  :this

代碼展現:

class MyClass
    {
        // 聲明一個名爲"myVal"的整型字段
       public int myVal = 10;

        // 聲明一個構造函數,該函數帶一個名爲"myVal"的參數
        public MyClass(int myVal)
        {
            // "this"表示MyClass類的當前實例
            // 在這裏經過this能夠在語義上區分紅員名myVal和參數名myVal
            this.myVal += myVal;
        }
    }

  

3)、聲明索引器。(PS:這個會在後續的博客中更新)

 代碼展現:

 /// <summary>
 /// 
 /// </summary>
 public NameValueCollection Attr = new NameValueCollection();
 
 /// <summary>
 /// /*************************/
 /// /* this用法3:聲明索引器 */
 /// /*************************/
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public string this[string key]
 {
     set
     {
         Attr[key] = value;
     }
 
     get
     {
         return Attr[key];
     }
 }

4)、擴展對象的方法

代碼展現:

/// <summary>
///Person 的摘要說明
/// </summary>
public class Person
{   /// <summary>    
    /// 性別    
    /// </summary>    
    public string Sex { set; get; }
}
 
 
/// <summary>
/// 輔助類
/// </summary>
public static class Helper
{
 
    /// <summary>
    /// /*****************************/
    /// /* this用法4:擴展對象的方法 */
    /// /*****************************/
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    public static string GetSex(this Person item)
    {
        return item.Sex;
    }
}
調用:

Person person = new Person();
person.GetSex();

  

本篇就到這裏了,最後打個小廣告:QQ羣: .NET 一步步一幕幕  羣號:590170361 (加羣備註:博客園看到的)

相關文章
相關標籤/搜索