實現多態的方式——抽象類


2、抽象類

  抽象類的特點:

  1)、抽象類中的抽象成員必須標記為abstract,並且不能有任何實現。

      方法不能有任何實現是指,方法沒有大括號,也沒有方法體。

      只有大括號,沒有方法體的方法叫做空實現。

  2)、抽象成員必須標記在抽象類中

  3)、抽象類是有構造函數的,但抽象類不能被實例化

  4)、子類繼承抽象類后,必須把父類中的所有抽象成員都重寫。(除非子類也是一個抽象類,則可以不重寫)

      注意:在重寫抽象成員的時候,必須在前面加上override標記,否則編譯器會報錯。用虛方法實現多態的話,也要加上override標記,但省略override,編譯器不會報錯。

  5)、抽象成員的訪問修飾符不能是private

  6)、在抽象類中可以包含實例成員,並且它們可以不被子類實現

  7)、如果父類的抽象方法中有參數。那么,繼承這個抽象父類的子類在重寫父類的方法的時候,必須傳入對應的的參數。

      如果抽象父類的抽象方法中有返回值,那么子類在重寫這個抽象方法的時候,也必須要寫上返回值。

     也就是說,子類在重寫抽象父類的抽象方法的時候,必須保證方法的簽名與父類的方法簽名一致。(方法的簽名:方法的參數和返回值)

   

  什么時候使用抽象類:在已有的幾個類中,如果說我們可以抽象出一個父類,並且父類中必須寫上這幾個子類共有的一個方法,且不知道如何去寫這個方法。

  圓形和矩形都有一個共同的父類:形狀,但形狀卻是抽象的,我們無法計算它的面積和周長,所以必須寫成抽象類。而圓形和矩形,它們計算面積和周長的方法也是不同的。這樣,我們就必須對形狀這個抽象類中,計算面積和周長的方法進行重寫。

    class Program { static void Main(string[] args) { //使用多態求矩形的面積和周長以及圓形的面積和周長
            Shape shape = new Square(5, 6); //new Circle(5);
            double area = shape.GetArea(); double perimeter = shape.GetPerimeter(); Console.WriteLine("這個形狀的面積是{0},周長是{1}", area, perimeter); Console.ReadKey(); } } public abstract class Shape { public abstract double GetArea(); public abstract double GetPerimeter(); } public class Circle : Shape { private double _r; public double R { get { return _r; } set { _r = value; } } public Circle(double r) { this.R = r; } public override double GetArea() { return Math.PI * this.R * this.R; } public override double GetPerimeter() { return 2 * Math.PI * this.R; } } public class Square : Shape { private double _height; public double Height { get { return _height; } set { _height = value; } } private double _width; public double Width { get { return _width; } set { _width = value; } } public Square(double height, double width) { this.Height = height; this.Width = width; } public override double GetArea() { return this.Height * this.Width; } public override double GetPerimeter() { return (this.Height + this.Width) * 2; } }

 

  抽象類也可以包含抽象的屬性,因為屬性的本質是 get、set這兩個方法。

    class Program { static void Main(string[] args) { //狗狗會叫 貓咪會叫
 Animal a = new Cat();//new Dog();
 a.Bark(); Console.ReadKey(); } } public abstract class Animal { public Animal(int age) { this.Age = age; } public virtual void T() { Console.WriteLine("動物有聲明"); } private int _age; public int Age { get { return _age; } set { _age = value; } } //Bark()沒有任何實現
        public abstract void Bark(); public abstract string Name { get; set; } //Test()只有大括號,沒有方法體,是空實現
        public void Test() { //空實現
 } } public class Dog : Animal { public override void Bark() { Console.WriteLine("狗狗旺旺的叫"); } public override string Name { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } } public class Cat : Animal { public override void Bark() { Console.WriteLine("貓咪喵喵的叫"); } public override string Name { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } }

 

關於抽象類需要注意的幾點:

  1)需要用abstract關鍵字標記

  2)抽象方法不能有任何方法實現

  3)抽象成員必須包含在抽象類中

  4)由於抽象成員沒有任何實現,所以子類必須將抽象成員重寫(以override來標記)。

  5)抽象類不能被實例化

  6)抽象類的作用:為了讓子類繼承

  7)抽象方法不能用static修飾  

    因為:抽象方法是沒有任何方法實現的,如果直接通過類名來調用,這樣的方法無法執行,沒有任何意義;

       能調用抽象方法的只能是重寫了抽象方法的子類的對象(如果抽象類的子類也是抽象類的話,就無法調用)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM