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修飾
因為:抽象方法是沒有任何方法實現的,如果直接通過類名來調用,這樣的方法無法執行,沒有任何意義;
能調用抽象方法的只能是重寫了抽象方法的子類的對象(如果抽象類的子類也是抽象類的話,就無法調用)
文章列表