C#中的構造函數、重寫與重載

默認構造函數都從父類object繼承了無參的構造方法。
1、類在初始化實例化對象(new)的時候將默認調用的是類中的默認構造函數(即無參的構造函數);
2、爲方便初始化數據,通常會構造函數(即構造函數需要帶參數,方法名與類名、無參的方法名一致,只是參數個數不一致),那麼在實例化對象(new)的時候就可以使用要帶參數的構造函數,以便初始化數據。
示例:
類Monitor,包含屬性String height;String width
public Monitor(){}            //無參的構造函數即默認構造函數,一般可不寫,編譯器自動創建
public Monitor(String height,String width){}
在main方法裏我做初始化動作
Monitor monitor=new Monitor();//實例化時不帶參數,即使在Monitor類裏面帶有N多個帶參數的構造函數,但這種方式如果要賦值,需手動賦值,如:monitor.height=100;monitor.width=200;
Monitor monitor2=new Monitor("100","200");//這種方式是帶參數的構造函數
    主要用來在創建對象時初始化對象 即爲對象成員變量賦初始值,總與new運算符一起使用在創建對象的語句中,特別的一個類可以有多個構造函數 可根據其參數個數的不同或參數類型的不同來區分它們,即構造函數的重載


  1.構造函數的命名必須和類名完全相同;而一般方法則不能和類名相同.
  2.構造函數的功能主要用於在類的對象創建時定義初始化的狀態.它沒有返回值,也不能用void來修飾.這就保證了它不僅什麼也不用自動返回,而且根本不能有任何選擇.而其他方法都有返回值.即使是void返回值,儘管方法體本身不會自動返回什麼,但仍然可以讓它返回一些東西,而這些東西可能是不安全的.
  3.構造函數不能被直接調用,必須通過new運算符在創建對象時纔會自動調用,一般方法在程序執行到它的時候被調用.
  4.當定義一個類的時候,通常情況下都會顯示該類的構造函數,並在函數中指定初始化的工作也可省略,編譯器會提供一個默認的構造函數.此默認構造函數是不帶參數的.而一般方法不存在這一特點
定義:
class A
{
public A(){}
}

使用:
A a=new A();//在這裏,A()就是就是構造函數。
需要注意的一點是,如果類裏面沒有定義構造函數,編譯器也會自動生產一個空構造函數,類的各個成員都賦上默認值。
但是如果在類裏面只定義了一個私有的構造函數的時候,那麼這個類將不能被實例化。
class A
{
string a;
private A() { }//這個類不能被實例化
} 

如果我們定義了帶參數的構造函數,而沒有定義不帶參數的構造函數,那麼在實例化這個類的對象的時候必須提供參數。
class A
{
string a;
public A(string str) {a=str; }
} 
不能這麼實例化對象 A a=new A();
構造函數分爲動態構造函數和靜態構造函數。
動態構造函數是類或結構實例化時,爲其分配內存空間,完成類或結構當中成員變量的初始化工作。動態構造函數可以重載,即相同構造函數名稱擁有不同類型和數目的多個構造函數。帶參數的構造函數和不帶參數的構造函數沒有本質區別,帶參數的構造函數可以通過傳入的變量控制或者直接初始化其中的成員變量,在構造函數中可以爲成員變量初始化默認值。
靜態構造函數不允許攜帶參數,即一個類中只允許有一個靜態構造函數。它在第一次訪問靜態成員或者第一次實例化動態該類的對象之前調用。



override是重寫(覆蓋)了一個方法,以實現不同的功能。一般是用於子類在繼承父類時,重寫(重新實現)父類中的方法。
重寫(覆蓋)的規則:
   1、重寫方法的參數列表必須完全與被重寫的方法的相同,否則不能稱其爲重寫而是重載.
   2、重寫方法的訪問修飾符一定要大於被重寫方法的訪問修飾符(public>protected>default>private)。
   3、重寫的方法的返回值必須和被重寫的方法的返回一致;
   4、重寫的方法所拋出的異常必須和被重寫方法的所拋出的異常一致,或者是其子類;
   5、被重寫的方法不能爲private,否則在其子類中只是新定義了一個方法,並沒s有對其進行重寫。
   6、靜態方法不能被重寫爲非靜態的方法(會編譯出錯)。
override就是子類將父類的方法重新實現了一遍。
new就是說這個方法就是子類自己的,跟父類沒有任何繼承關係關係,僅僅是重名

二、overload是重載,一般是用於在一個類內實現若干重載的方法,這些方法的名稱相同而參數形式不同。

重載的規則

   1、在使用重載時只能通過相同的方法名、不同的參數形式實現。不同的參數類型可以是不同的參數類型,不同的參數個數,不同的參數順序(參數類型必須不一樣);

   2、不能通過訪問權限、返回類型、拋出的異常進行重載;

   3、方法的異常類型和數目不會對重載造成影響;

多態的概念比較複雜,有多種意義的多態,一個有趣但不嚴謹的說法是:繼承是子類使用父類的方法,而多態則是父類使用子類的方法。

一般,我們使用多態是爲了避免在父類裏大量重載引起代碼臃腫且難於維護。

舉個例子:

public class Shape

{

   public static void main(String[] args){

     Triangle tri = new Triangle();

     System.out.println("Triangle is a type of shape? " + tri.isShape());// 繼承

     Shape shape = new Triangle();

     System.out.println("My shape has " + shape.getSides() + " sides."); // 多態

     Rectangle Rec = new Rectangle();

     Shape shape2 = Rec;

     System.out.println("My shape has " + shape2.getSides(Rec) + " sides."); //重載   

   }

   public boolean isShape(){

     return true;

   }

   public int getSides(){

     return 0 ;

   }

   public int getSides(Triangle tri){ //重載

     return 3 ;

   }

   public int getSides(Rectangle rec){ //重載

    return 4 ;

   }

}

class Triangle extends Shape

{

   public int getSides() { //重寫,實現多態

     return 3;

   }

}

class Rectangle extends Shape

{

   public int getSides(int i) { //重載

    return i;

   }

}

注意Triangle類的方法是重寫,而Rectangle類的方法是重載。對兩者比較,可以發現多態對重載的優點:

如果用重載,則在父類裏要對應每一個子類都重載一個取得邊數的方法;

如果用多態,則父類只提供取得邊數的接口,至於取得哪個形狀的邊數,怎樣取得,在子類裏各自實現(重寫)


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