1. 程式人生 > >c#基礎 類與結構體的區別 繼承

c#基礎 類與結構體的區別 繼承

類是引用型別的,變數中儲存的數物件的地址,s1和s2中儲存但是同一個物件的地址

結構體是值型別的,複製時,是將s3中的成員拷貝給s4的成員,s3,s4是兩個結構體變數。

結構體中不帶參的建構函式會一直存在,不會因為自己建立建構函式而消失

因為不帶引數的建構函式一直存在,所以不能自己建立不帶引數的建構函式。

結構體初始化可以在宣告時呼叫建構函式,也可以聲明後一個成員一個成員的賦值

結構體可以不用new加建構函式初始化,但是必須要先給每一個成員賦值之後才可以使用該結構的結構體變數

靜態建構函式

類中靜態建構函式呼叫時機,:第一次建立物件,或第一次訪問靜態成員

結構體中,1、第一次呼叫靜態建構函式建立物件時(呼叫預設靜態函式不會觸發)

2、或第一次呼叫靜態成員,訪問靜態成員會觸發,訪問非靜態成員不會觸發3、第一次呼叫方法

結構體變數不可以賦值為空,類的物件可以

單例模式

單例模式就是將建構函式寫成私有的,不能直接呼叫建構函式只能通過一個公有的方法呼叫建構函式

private Person (string _name,int _age)
        {
            name = _name;
            age = _age;
        }

//在方法中實現單例,如果為NULL就建立一個物件,從第二次開始就不為null返回的還是同一個物件,所以稱為單例模式

  public static Person Create()
        {
            if (linken == null)//宣告時要將linken宣告為靜態欄位,因為Create()為靜態方法
            {
                return linken = new Person("a",20);
            }
            else
            {
                return linken;
            }
        }

索引器

類中的普通陣列,如果要達到在類的外部訪問的目的,就需要寫成公共的,這不符合封裝的思想

class MainClass
	{
		public static void Main()
		{
			Vector v = new Vector(5);

			for (int i = 0; i < 5; i++)
			{
//1.陣列成員要宣告成公有
			//2.訪問陣列中的元素時要先訪問陣列再訪問元素
			//v.array[i] = i;
				v[i] = i;
			}
//通過索引器,首先陣列可以宣告成私有的了,然後訪問陣列中的元素也不用先訪問陣列再訪問元素了,
			//可以直接通過索引器來訪問陣列中的元素
			for (int i = 0; i < 5; i++)
			{
				Console.WriteLine(v[i]);
			}
		}
	}
	//public class Vector
	//{
	//	public int[] array;

	//	public Vector(int n)
	//	{
	//		array = new int[n];
	//	}
	//}
有陣列成員的了才寫索引器,目的是方便陣列中成員的訪問
   public class Vector
    {
        private int[] array;
        public Vector(int n)
        {
            array = new int[n];
        }
        public int this[int index]
        {
            get { return array[index]; }
            set { array[index] = value; }
        }
    }
一個類可以有多個索引,但是下標需要時不同的型別。

繼承:子類將獲得父類中除建構函式解構函式外 的所有成員。靜態類不能被繼承。對父類繼承下來的欄位,要引用父類的建構函式進行初始化

public Horse(string _name,int _age,string _color):base(_name,_age,_color)
 {
 }

子類不能對父類的私有成員進行訪問,它只能對保護成員進行訪問。子類可以通過呼叫共有或者保護方法間接的對私有成員訪問

protected修飾符:當前類和子類可以訪問。

//密封類不能被繼承使用sealed關鍵字類定義密封類

public sealedclass Person

子類建構函式如果不顯示呼叫父類的建構函式,就會自動呼叫父類不帶引數的建構函式

        public Student (string _name,int _age)

        {

        }

初始化一個子類時,除了會呼叫子類的建構函式之外,同時也會呼叫基類的建構函式。

//子類的初始化順序 1.初始化例項欄位2.呼叫父類的建構函式初始化父類的那段成員3.呼叫自己建構函式初始化自己擴充套件到成員

Student t = new Student("aaa", 29, 99);
            t.print();
            //Student shi Person的子類,可以把子類物件複製給父類引用
            Person p = new Student("bb", 26, 94);
            p.print();//p2雖然是父型別的引用,但實際指向的物件是子類物件

//在程式執行過程中程式會根據實際隊形的型別低啊用該物件中的虛方法
  //相同型別的物件呼叫相同的方法卻表現不同的行為就叫做多型
            //如果不重寫就不能實現多型

            //實現多型的前提是重寫虛方法

            //父類物件不可以當成子類物件來使用

//虛方法使用virtual關鍵字

public virtual void print()
        {
            Console.WriteLine("{0}{1}",name,age);
        }

 public abstract class Animal
    {
        //用abstract 修飾方法時,表示純虛方法,沒有函式體,函式頭後邊直接跟分號,
        //需要在子類中進行重寫,子類如果不重寫純虛方法就會出錯
        //純虛方法只能出現在抽象類中
        public abstract void voice();

    }
    public class Horse:Animal
    {
        //如果不希望子類繼續重寫該虛方法,就宣告成sealed方法
        //sealed宣告類時,表示密封類,不能被繼承,宣告方法時,便是子類不能繼續重寫
        //用abstract 修飾方法時,表示純虛方法,沒有函式體,函式頭後邊直接跟分號,
        //需要在子類中進行重寫,子類如果不重寫純虛方法就會出錯

        public override void voice()
        {
            Console.WriteLine("voice in horse");
        }
    }
public class Whitehorse:Horse
    {
        // horse 中的voice本身就是虛方法,可以直接重寫
        //horse中的voice如果加sealed關鍵字就不能重寫了
//        public  void voice()
//        {
//            Console.WriteLine("voice in white");
//        }
    }
//沒有指定父類的類,父類預設就是object類
    public class Animal
    {
        private void voice()
        {
            Console.WriteLine("voice of animal");
        }
    }
public override string ToString()
        {
            //通過string.format建立字串
            return string.Format("{0},{1}",name,age);
        }