using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int i;
double radius;
double result;
Console.WriteLine("要计算圆的周长还是面积,计算周长请输入0,计算面积请输入1");
i = int.Parse(Console.ReadLine());
Console.WriteLine("请输入要计算的圆的半径");
radius = int.Parse(Console.ReadLine());
Circle cl = Factory.CreatCircle(i, radius);
result = cl.Compute();//“一个人可以做不同的事”,智能化
Console.WriteLine("计算结果是:" + result);
Console.ReadLine();
}
interface Circle
{
double Compute();
}//接口只须有个计算(不管是面积还是周长)的方法声明就行了
class Area:Circle//计算面积的类继承接口
{
private double radius;
public Area(double r)
{
radius = r;
}
public double Compute()
{
return 3.14 * radius * radius;
}//实现真正的计算
}
class Round : Circle//与计算面积的类一样继承接口
{
private double radius;
public Round(double r)
{
this.radius = r;
}
public double Compute()
{
return 3.14 * 2 * radius;
}//实现真正的计算
}
class Factory//简单工厂
{
public static Circle CreatCircle(int i, double radius)
{
Circle cl = null;
switch (i)
{
case 0:
cl = new Round(radius);
//此处是不是会让你怀疑为什么可以“Circle cl = new Round()”呢?见注解
break;
case 1:
cl = new Area(radius);
break;
}
return cl;
}
}
}
}
/*
以上代码直接复制粘贴可运行看效果,但或许你会有些不太明白这能说明什么,且看Main()里的两条语句,Circle cl = Factory.CreatCircle(i, radius);
result = cl.Compute();
这里创建了一个接口Circle的实例cl,接着调用接口的Compute()方法得到结果。有没有发现,在Main()里我们只要知道用户想要什么结果,而无须关心自己要是计算面积或是周长只须一个cl.Compute()却能得到结果,关心是计算面积还是周长的事已经交到Factory(工厂)类里了,而事实上工厂也不关心怎么计算面积或是周长,关心它们的事已经被交到继承了Circle接口的Area跟Round两个类里去了。
这样做有什么好处呢,假设圆还有一个属性叫半周长(HalfRound),我们若要计算它,便只须再加一个类class HalfRound:CirCle{}来实现半周长的计算即可,其它地方无须再改(当然,我们要让用户知道我们已经可以计算圆的半周长了)。
是不是感觉CirCle已是无所不能的了,确实可以这么说,只要是求圆的属性,我们都可以让它来做。这正是接口的职责所在,它就是要让我们看上去一个类可以智能地做多件事一样。
而如果不用接口,而用C的面向过程编程的话,楼主可以试一下,对比两种方法所写的代码的可复用与可维护,相信你会有所发现的。
除了这点,通过以上的Factory还可以把各类的职责细分,减小类与类的关联,也就是面向对象一大要求——低偶合。
至于Circle cl = new Round()为什么可行,这就是C#的语法了,用接口声明的一个对象可以用继承了它的子类来实例化,记着就行了,这个真的没有为什么。。。
*/
1,定义一个抽象类或者接口,表示图形,其中包含2个方法:求面积和求周长
2,定义具体类实现这个接口或继承这个抽象类,实现其中定义的函数。
3,调用的时候,定义这个接口类型或抽象类对象,然后根据实例化的不同子类,来调用不同的方法,——即类的多态性。
比如,下面用接口来实现:
interface IDraw
{
float Area();
float Round();
}
class Square : IDraw
{
private float _x;
public Square(float x){this._x = x;}
public float Area()
{ return _x * _x; }
public float Round()
{ return _x * 4; }
}
class Rectangle : IDraw
{
private float _x, _y;
public Rectangle(float x, float y){this._x = x; this._y = y;}
public float Area()
{ return _x * _y; }
public float Round()
{ return _x * 2 + _y * 2; }
}
class Circle : IDraw
{
private float _x;
private double PI=3.14;
public Circle(float x){this._x = x; }
public float Area()
{ return _x * PI*2; }
public float Round()
{ return _x * _x *PI; }
}
void Main()
{
IDraw draw;
draw = new Square(5);
draw.Area(); // 计算正方形面积
draw.Round();// 计算正方形周长
draw = new Rectangle(5,10);
draw.Area(); // 计算长方形面积
draw.Round();// 计算长方形周长
draw = new Circle(5);
draw.Area(); // 计算圆面积
draw.Round();//计算圆周长
}
多态性的好处很明显,方便以后扩充功能,且不影响原有的功能,你再加入椭圆形,菱形等,都只要定义新的类实现IDraw即可。
在调用方也实现了统一的接口,不管什么图形,都是用Area()和Round()去算面积和周长。