您的位置:首页 > 其它

关于接口与多态的经典讨论

2011-10-28 01:03 197 查看
小明在家跟妈妈说,我要吃水果
妈妈去水果摊去买水果,看看哪个便宜就买哪个。
最后买回去了橘子。
这就叫抽象类。

你在街上被人群殴,有人用棍子打你,有人用脚踹,有人用拳头。反正你费血了。
这就叫接口。

这样吧,你的电脑上只有一个USB接口。
这个USB接口可以接MP3,数码相机,摄像头,鼠标,键盘等。。。
好了,这里就有一个问题:所有的上述硬件都可以公用这个接口,而且有很好的扩展性。
这就是接口

你有一辆宝马的汽车,有一天,你拿它去越野了,轮胎,哎,自然爆掉,现在你想换轮胎。
你不想换宝马的轮胎,太贵。
你不想换qq的轮胎,不好使。
你想换OOOO的,换了,好用。
这就是抽象类。

接口和抽象类都是多态。
假设
我要拿遥控器打开电器
接口和抽象类多态的侧重点不同。
接口的侧重点在遥控器
多态的侧重点在电器

1、首先让理解接口和抽象类的使用环境
横看接口竖看类:横向扩展使用接口;纵向扩展使用抽象基类;横向和纵向都要扩展,使用抽象基类继承接口。
在差异较大的对象中追求功能上的共性时,使用接口。
在差异较小的对象中追求功能上的不同时,使用抽象基类,因为抽象基类可以包含实现的成员。

比如说,篮球场上有前锋(forward)、中锋(center)、后卫(guard),无论哪个位置,前锋、中锋和后卫都有防守和进攻的责任,另外中锋专注于篮板。这时候,可以定义运动员(player)抽象基类,抽象基类中定义虚(virtual)方法:Attack(进攻)、Defense(防守),然后让前锋类、中锋以及后卫类去重载(override)。
class Player
{
public virtual void Attack(){}
public virtual void Defense(){}
}
class Forward:Player
{
public override void Attack(){//前锋的进攻}
public override void Defense(){//前锋的防守}
}
class Center:Player
{
public override void Attack(){//前锋的进攻}
public override void Defense(){//前锋的防守}
public void Rebound(){//抢板}
}
class Guard:Player
{
public override void Attack(){//前锋的进攻}
public override void Defense(){//前锋的防守}
}
class PlayerInvoke:Player
{
private Player _player;
public PlayerInvoke(Player player)
{
_player=player;
}
public void Attack()
{
_player.Attack();
}
public void Defense()
{
_player.Defense();
}
}
调用的时候
Player player=new Forward();
Player player=new Center();
Player player=new Guard();
PlayerInvoke pi=new PlayerInvoke(player);
pi.Attack();
这是简单工厂实际模式的简单应用,此时你要查看哪个位置运动员的防守、进攻不是灵活多了?而且,在增加其它位置的运动员时,易于扩展和维护。

2、抽象基类:实现代码复用
人分男人和女人,不论男人女人都有吃饭(这就是共性,当然还有很多其它共性),但是男人和女人有其它行为是不一样的(比如上厕所的方式,^_^低俗)..这时候可以把男人和女人的共性拿出来,然后使用集成,这样男人女人类都复用这些代码。
abstract class Person
{
public void Eating()
{//人吃饭}
public virtual void WC()
{
//男人和女人类重写
}
}
class Female:Person
{
public override void WC(){}
}
class Male:Person
{
public override void WC(){}
}

3、接口:面向接口编程模式、适配器模式等
接口表示调用者和设计者的一种约定,在多人合作开发同一个项目时,事先定义好相互调用的接口可以大大提高开发的效率。接口是用类来实现的,实现接口的类必须严格按照接口的声明来实现接口提供的所有功能。有了接口,就可以在不影响现有接口声明的情况下,修改接口的内部实现,从而使兼容性问题最小化。

当其他设计者调用了接口后,就不能再随意更改接口的定义,否则项目开发者事先的约定就失去了意义。但是可以在类中修改相应的代码,完成需要改动的内容。

抽象类

抽象类是指这个类是不完全可用的,只能作为其它类的基类。抽象类和其它非抽象类的最大区别之处在于:抽象类不能被实例化。

1) 抽象类和接口都不能被实例化

2)接口是完全抽象的成员集合;抽象类可以完全实现,也可以部分实现或者根本不实现,从而封装继承类的通用功能

3) 抽象类只能作为基类使用,接口可以从其它基接口继承

4)接口成员默认访问方式是public,接口成员定义不能包含任何访问修饰符;抽象类则不然

5) 接口中不能声明任何种类的静态成员,抽象类则可以

6) 接口成员必须只能是方法、属性、索引器和事件,且不提供实现;抽象类还可以声明字段以及实现的方法和属性等

7) 抽象方法只能在抽象类中声明

interface IUSB
{
void Connect();
void Close();
bool SendByteToDevice(long location,byte b);
byte GetByteFromDevice(long location);
}

class MP3:IUSB
{
void Connect()
{
MessageBox.Show("MP3 Connected");
}

void Close()
{
MessageBox.Show("MP3 Removed From USB Interface");
}
bool SendByteToDevice(long location,byte b)
{
return false;
}
byte GetByteFromDevice(long location)
{
return 0;
}
}

class Mouse:IUSB
{
void Connect()
{
MessageBox.Show("Mouse Connected");
}

void Close()
{
MessageBox.Show("Mouse Removed From USB Interface");
}
bool SendByteToDevice(long location,byte b)
{
return false;
}
byte GetByteFromDevice(long location)
{
return 0;
}
}

main(string[] fucks)
{
IUSB usb=new MP3();
usb.Connect();
usb.Close();

usb=new Mouse();
usb.Connect();
usb.Close();
}

上面的就是接口。

接口主要用于多态化方法。

class BaoMaCar
{
AbLunTai LunTai= new BaoMaLunTai();
void runLongTime(){}
}

abstract class AbLunTai
{
string Name="AbLunTai";
}

class BaoMaLunTai
{

string Name="BaoMaLunTai";
}

class OOOOLunTai
{

string Name="OOOOLunTai";
}

main(string[] gays )
{
BaoMaCar car=new BaoMaCar();
car.runLongTime();
car.LunTai=new OOOOLunTai();
}

这就是抽象类,多用于多态对象。

关于重用:
LunTai dai = new BaoMaLuntai();
Console.WriteLine(dai.size);
public abstract class LunTai
{
public int size = 50;
}

public class BaoMaLuntai
{

}

public class OOOOLuntai
{

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: