C#教程(2)-----對象和類型篇

一:類和結構

類和結構其實就是實現對象的模板,每個對象都有數據和處理數據的方法。

類和結構的不同點:
a、類支持繼承,結構不支持繼承
b、類是引用類型,存儲在堆(heap)上,結構是值類型,存儲在棧(stack)上
c、類的關鍵字(class),結構的關鍵字(struct)。

示例1:

class PhoneCustomer
{
            public const string DayOfSendingBill = "Monday";
            public int CustomerID;
            public string FirstName;
            public string LastName;
}

兩者都是用new關鍵字創建並對其進行初始化

二:類

類包含成員,成員分爲靜態成員和實例成員。靜態成員屬於類,實例成員屬於對象。即靜態字段的值在每個對象中都是相同的,實例字段每個對象都可以有不同的值。靜態成員關聯了static修飾符

成員 說明
字段 字段是類的數據成員,它是類型的一個變量,該類型是類的一個成員
常量 常量與類相關。編譯器使用真實值代替常量
方法 與特定類相關的函數
屬性 可以從客戶端訪問的函數組
構造函數 實例化對象是自動調用的特殊函數
索引器 允許對象用訪問數組的方式訪問
運算符 運算符執行的最簡單的操作就是執行加法和減法
事件 事件是類成員,在發生某些行爲時調用
析構函數 類似於構造函數的語法
類型 類可以包含內部類

1.字段

字段時與類相關的變量。
實例化示例1的對象之後,就可以用如下方法訪問:

var customer1 = new PhoneCustomer();
Console.WriteLine(customer1.CustomerID);

使用const聲明常量,如果將其聲明爲public,就可以在類外訪問它。
最好不要把字段聲明爲public。

2.屬性

**概念:**他是一個方法或一對方法,在客戶端代碼看來,他們是一個字段。
例如:

class PhoneCustomer
        {
            private string _firstName;
            public string FirstName
            {
                get { return _firstName; }
                set { _firstName = value; }
            }
        }

包括get和set兩個訪問器,用來獲取和設置字段的值

a、自動實現的屬性

如果屬性的set和get訪問器中沒有任何的邏輯,就可以使用自動實現的屬性。這種書行賄自動實現後被成員變量。
例如:

public int Age { get; set; } 

不需要聲明私有字段。編譯器就會自動創建它。自動實現的屬性可以使用屬性初始化器來初始化

public int Age { get; set; } = 42;

b、屬性的訪問修飾符

C#允許給屬性的get和set訪問器設置不同的訪問修飾符,所以可以有共有的get訪問器和私有的set訪問器。有卒於控制屬性的設置方式和時間;在get和set訪問器中,必須有一個具備屬性的訪問級別;
例如:

public string FirstName
            {
                get { return _firstName; }
                private set { _firstName = value; }
            }
public int Age { get;private set; } = 42;

3.方法

a、方法的聲明

形式:

修飾符 返回值類型 方法名(參數列表)
{
	方法體
}

例如:

private string getName(string id)
{
	return Name;
}

b、 表達式體方法

如果方法的實現只有一條語句,C#6提供一個簡化方法:表達式體方法
捨棄了花括號和return關鍵字,使用=>區分左邊聲明和右邊實現代碼
例如:private string getName(string id)=>Name;

c、調用方法

實例:

using System;
using System.Threading;

namespace ConsoleApp2
{
    class Math
    {
        public int value{get; set;}
        public int getSquare() => value * value;
        public static int getSquareOf(int x) => x * x;
        public static double GetPi() => 3.14159;

        static void Main(string[] args)
        {
            
            Console.WriteLine("Pi is "+Math.GetPi());
            Console.WriteLine($"Pi is {Math.getSquareOf(5)}");

            var math = new Math();//實例化一個對象

            math.value = 30;
            Console.WriteLine($"value field of math variable contains{math.value}");
            Console.WriteLine($"square if 30 is {math.getSquare()}");
            
            Thread.Sleep(5000);//睡眠5000毫秒,也就是5秒
        }
    }
}

結果:
在這裏插入圖片描述
理解上述實例就能輕鬆掌握調通方法的技巧。

d、方法的重載

定義:方法名相同,但方法的參數個數和數據類型不同。
在這裏插入圖片描述
(上述例子只爲重載而重載,沒有任何實際意義)

e、可選參數

假如一個方法有兩個參數,其中有一個參數調用時可能會用到,也可能時默認值。這時候我們就可以將其設置爲可選參數。例:

public static int getSquareOf(int x,int y = 42) => x * x * y * y;

我們調用的方法有下列兩種;

Math.getSquareOf(5);
或
Math.getSquareOf(5,1);

注意:可選參數可以有有多個,可選參數必須放在參數的最後面。
例如:

public static void  getSquareOf(int x, int y = 5, int z = 4)
        {
            Console.WriteLine($"x is {x}");
            Console.WriteLine($"y is {y}");
            Console.WriteLine($"z is {z}");
        }

調用示範:

Math.getSquareOf(1,z:3);
Math.getSquareOf(1,y:2);

f、個數可變參數

除了可選參數外,還有一種方法可以實現參數個數可變的方法;

實例:(注意getSquareOf方法)

using System;
using System.Threading;

namespace ConsoleApp2
{
    class Math
    {
        public int value{get; set;}
        public int getSquare() => value * value;
        public static void  getSquareOf(params int[] x)
        {
            foreach (int temp in x)
            {
                Console.Write(temp+" ");
            }
            Console.WriteLine();//換行
        }
        public static double GetPi() => 3.14159;

        static void Main(string[] args)
        {

            Math.getSquareOf(1);
            Math.getSquareOf(1,2,3,4);
            Math.getSquareOf(1,2,3,4,5,6,7,8,9,10);

            
            Thread.Sleep(5000);//睡眠5000毫秒,也就是5秒
        }
    }
}

結果:
在這裏插入圖片描述
如果想將不同類型的參數傳給方法,可以將int數組換成obiect數組。如果params關鍵字與其他參數一起使用,需要將其放在最後,並只能使用一次。

4.構造方法

構造函數名必須與類名相同,但是沒有返回值。
例如:

class Math
    {
        public Math()
        {
        }
     }

如果開發者沒有給類提供構造函數,那麼編譯器就會生成一個極其簡單的構造函數用來初始化工作。

a、在構造函數中調用其它構造函數

有類如下👇

class Math
    {
        int x;
        int y;
        
        public Math(int _x)
        {
            x = _x;
            y = 2;
        }
        public Math(int _x,int _y)
        {
            x = _x;
            y = _y;
        }
        //etc

咋一看這個代碼,有兩個構造函數,函數體大致相同,只有y變量操作不同,如果操作再多一點,就會造成代碼重複,啥玩應 。那麼,他來了!!!!!!(構造函數初始化器
👏👏👏

class Math
    {
        int x;
        int y;
        
        public Math(int _x):this( _x, 2)
        {
        }
        public Math(int _x,int _y)
        {
            x = _x;
            y = _y;
        }
        //etc

是不是感覺變好看了呢!this關鍵字只調用參數最匹配的那個構造函數

C#構造函數初始化器可以包含對同一個類的構造函數的調用(上述語法),也可以對積累的構造函數進行調用(使用相同的語法,但應該將this換成base),初始化器不能有多個調用

b、靜態構造函數

可以編寫無參的靜態構造函數是C#的特徵之一。這種構造函數只執行一次,通常在第一次實用類之前執行。

同學A:爲啥要寫靜態構造函數?”
“老師:不知道”
老師:”類有一些靜態字段或屬性,需要在使用前進行初始化。

注意:靜態構造函數沒有訪問修飾符,其他C#代碼從不顯示調用它,.NET運行庫在加載類是調用它,且只能訪問類的靜態成員
使用範例:

using System;
using System.Drawing;
using System.Threading;

namespace ConsoleApp2
{
    public static class UserPreferences
    {
        public static Color BackColor { get; }
        static UserPreferences()
        {
            DateTime now = DateTime.Now;
            if (now.DayOfWeek == DayOfWeek.Saturday || now.DayOfWeek == DayOfWeek.Sunday)
            {
                BackColor = Color.Green;
            }
            else
            {
                BackColor = Color.Red;
            }
        }
        static void Main(string[] args)
        {

            Console.WriteLine($"User-preferences:BackColor is : {UserPreferences.BackColor}");

            
            Thread.Sleep(5000);//睡眠5000毫秒,也就是5秒
        }
    }
}

如果理解了上述代碼,那麼恭喜你這節畢業了。👏👏👏👏

5.只讀字段

只讀字段用readonly修飾符聲明,只能在構造函數中分配值。與const不同,編譯器通過const,用他的值取代變量。與const相反,只讀字段可以作爲實例成員,這是需要加上static。

比如說一個文檔編輯程序,需要限制文檔最大打開數。現在顧客升級該程序後需要修改文檔最大打開數。顯然不能再源代碼中對其進行硬編碼,而是需要一個只讀字段來表示,每次打開程序時讀取。

public static class UserPreferences
    {
        private static readonly uint max_Count;
        static UserPreferences()
        {
            max_Count = DoSometh();
        }
        //etc

只讀屬性
在屬性定義中省略set訪問器就可以創建只讀屬性。
用readonly修飾符聲明字段只允許在構造函數中初始化屬性的值。

6.匿名類型

var關鍵字用於表示隱式類型化的變量,new和var關鍵字一起使用時可以創建匿名類型,匿名類型是一個繼承自object且沒有名稱的類。該類的定義從初始化器中推斷,類似於隱式類型化的變量。

var caption = new
            {
                firstName = "James",
                middleName = "T",
                lastName = "Kirk"
            };

在寫另一個匿名類型

var doctor = new
            {
                firstName = "w",
                middleName = "j",
                lastName = "s"
            };

那麼就可以說doctor和caption類型相同,當類型相同時,可以設置caption = doctor。
當設置的值來自於一個有存在對象可以這樣寫:

var doctor = new
            {
                caption.firstName,
                caption.middleName,
                caption.lastName
            };

7.枚舉

枚舉時一個值類型,包含一組命名的常量。示例如下:👇

    public enum color
        {
            red,
            green,
            blue
        }

可以聲明枚舉類型變量:

color c1 = color.red;

默認情況下,enum的類型是int。可以改爲其他整數類型(byte,short、int、帶符號的long和無符號的變量)。命名常量的值從0開始遞增。也可以改爲其他值

public enum color:short
        {
            red = 1,
            green = 2,
            blue = 3
        }

使用強制類型轉換可以把數字轉換爲枚舉值,或者把枚舉值轉換爲數字。

color c2 = (color)2;
short = number = (short)c2;

8.部分類

partial關鍵字允許把類、結構、方法或接口放在多個文件中。簡單的說就是把類、結構、方法或接口拆開放在不同的源文件下。
partial用法:將其放在class、struct或interface關鍵字前面。
部分類可以包含部分方法
例如:

public void MethodOne()
{
	ApartialMethod();
}
public partial void ApartialMethod()
{
}

9.擴展方法

擴展方法是給對象添加功能的一個選項,在不能使用繼承時,可以使用。
例如:(擴展string)

public static int GetCountOfWord(this string s) => s.Split().Length;

使用this關鍵字和第一個參數來擴展字符串,這個關鍵字定義了要擴展的類型

10.Object類

Tpstring()方法: 轉換爲字符串。
GetHashCode()方法: 如果對象放在名爲映射(散列表或字典)的結構中,就可以使用這個方法。
GetType方法: 返回一個從System.Object派生的類的一個實例。
MemberwiseClone方法: 複製對象並返回一個對副本的引用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章