实现多态的第二种方法也就是实用抽象类(Abstract),那么虚方法可以实现多态,抽象类也可以实现多态,那么到底什么时候使用抽象类呢
当父类中的方法不知道如何去实现的时候,可以考虑将父类写成抽象类,将方法写成抽象方法
抽象类几个特别注意的地方:
- 抽象成员必须标记为abstract,并且不能有任何实现,也就是没有方法体{}
- 抽象成员必须在抽象类中
- 抽象类中可以有抽象成员,也可以有非抽象成员,非抽象成员可以给子类使用
- 抽象类不能被实例化
- 子类继承抽象类后,必须把父类中的所有抽象成员都重写。
- 抽象成员的访问修饰符不能是private
- 抽象类是有构造函数的。虽然不能被实例化。可以 给子类用
- 如果父类的抽象方法中有参数,那么。继承这个抽象父类的子类在重写父类的方法的时候必须传入对应的参数。如果抽象父类的抽象方法中有返回值,那么子类在重写这个抽象方法的时候 也必须要传入返回值
写一个抽象类的例子,这个利用多态实现了计算不同形状的图形的周长和面积
//因为我们不知道各个形状图形计算周长和面积的方法是怎样的,所以我们选择抽象类实现
public abstract class Shape{
public abstract double GetArea();
public abstract double GetPerimeter();
}
//各个子类进行具体的实现,必须对抽象父类的所有抽象方法进行实现,并且有相同的标签
public class Circle : Shape
{
public Circle(double r)
{
this.R = r;
}
public double R { get; set; }
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
{
public double Height { get; set; }
public double Width { get; set; }
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;
}
}
下面我们在Main方法中调用一下
static class 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);
}
//shape在调用GetArea()方法和GetPerimeter()方法的时候会自动的找到对应的实例,并应用对应实例的方法
上面这个例子实现的多态,如果我们还想计算其他形状的面积额周长的时候,只需要继承抽象类,并实现抽象类中的抽象方法就行了
实现多态的第三种方式——接口实现多态