五、抽象基类与接口

5.1 抽象类与抽象方法

在一个类前面加上“abstract”关键字,此类就成为了抽象类。

对应的,一个方法类前面加上“abstract”关键字,此方法就成为了抽象方法。

abstract class Fruit   //抽象类

{

public abstract void GrowInArea();  //抽象方法

}

注意抽象方法不能有实现代码,在函数名后直接跟一个分号。

抽象类专用于派生出子类,子类必须实现抽象类所声明的抽象方法,否则,子类仍是抽象类。

抽象类一般用于表达一种比较抽象的事物,比如前面所说的“水果”,而抽象方法则说明此抽象类应该具有的某种性质,比如Fruit类中有一个抽象方法GrowInArea(),说明水果一定有一个最适合其生长的地区,但不同的水果生长地是不同的。

从同一抽象类中继承的子类拥有相同的方法(即抽象类所定义的抽象方法),但这些方法的具体代码每个类都可以不一样,如以下两个类分别代表苹果(Apple)和菠萝(Pineapple):

class Apple:Fruit  //苹果

{

public override void GrowInArea()

{

Console.WriteLine("南方北方都可以种植我。");

}

}

class Pineapple:Fruit   //菠萝

{

public override void GrowInArea()

{

Console.WriteLine("我喜欢温暖,只能在南方看到我。");

}

}

注意上述代码中的override关键字,这说明子类重写了基类的抽象方法。抽象类不能创建对象,一般用它来引用子类对象。

Fruit f;

f=new Apple();

f.GrowInArea();

f=new Pineapple();

f.GrowInArea();

运行结果:

南方北方都可以种植我。

我喜欢温暖,只能在南方看到我。

注意同一句代码“f.GrowInArea();”会由于f所引用的对象不同而输出不同的结果。可以看到,代码运行结果类似于上一节介绍的“虚方法调用”,两者没有本质差别。

可以按照以下公式编写代码:

抽象类 抽象类变量名=new 继承自此抽象类的具体子类名();

一个抽象类中可以包含非抽象的方法和字段。因此:

包含抽象方法的类一定是抽象类,但抽象类中的方法不一定是抽象方法。

5.2 抽象属性

除了方法可以是抽象的之外,属性也可以是抽象的,请看以下代码:

abstract class Parent

{

public abstract String Message   //抽象属性

{

get;

set;

}

}

class Child:Parent

{

private String _msg;

public override String Message

{

get

{

return _msg;

}

set

{

_msg=value;

}

}

}

使用代码:

Parent p=new Child();

p.Message="Hello";

5.3 接口

来看以下这句话:

鸭子是一种鸟,会游泳,同时又是一种食物。

如何在面向对象的程序中表达这种关系?

如果使用C++,可以设计成让鸭子(Duck)类继承自两个父类(鸟Bird和食物Food)。但在C#中所有的类都只能有一个父类,此方法不可行。

为了解决这一问题,C#引入了接口(interface)这一概念,并规定“一个类可以实现多个接口”。

(1)接口的定义与使用

关键字interface用于定义接口:

//定义两个接口

public interface  ISwim

{

void Swim();

}

public interface  IFood

{

void Cook();

}

接口可以看成是一种“纯”的抽象类,它的所有方法都是抽象方法。

可以用与继承相同的语法定义一个类实现某些接口:

//定义一个抽象类

public abstract class  Bird

{

public abstract void  Fly();

}

//继承自一个抽象类,实现两个接口

public class Duck : Bird, IFood, ISwim

{

//实现ISwim接口

public  void  Swim()

{

Console.WriteLine("是鸭子就会游泳");

}

//实现IFood接口

public void  Cook()

{

Console.WriteLine("鸭子经常被烧烤,北京烤鸭就很有名");

}

//实现抽象类Bird中的抽象方法

public override void  Fly()

{

Console.WriteLine("只有野鸭才会飞");

}

}

可以看到,抽象类定义了对象所属的类别,而接口实际上定义了一种对象应具有的行为特性。

可按以下公式使用接口:

接口类型名 变量名=new 实现了接口的类型名();

示例代码如下:

static void Main(string[] args)

{

Duck d = new  Duck();

//Duck对象d可以使用3种方法:

//1.自身定义的;

//2.父类定义的

//3.接口定义的

d.Fly();

d.Cook();

d.Swim();

//将子类(Duck)对象赋给基类变量

Bird b = d;

//现在只能使用基类定义的Fly()方法

b.Fly();

//将Duck对象赋给ISwin接口变量

ISwim s = d;

//现在只能使用接口定义的Swim()方法

s.Swim();

//将Duck对象赋给另一个实现的接口IFood接口变量

IFood f = d;

//现在只能使用接口定义的Cook()方法

f.Cook();

}

请读者仔细地阅读上述代码的注释,由于 Duck类继承自抽象基类  Bird,又实现了  ISwim和 IFood两个接口,所以,Duck对象拥有这三者所定义的所有方法,并且可以赋值给这三种类型的变量。

需要注意的是,虽然程序中始终都只有一个 Duck对象,但将其赋值给不同类型的变量后,其可以使用的方法是不一样的。

(2)显式实现接口

上面讲到,某个类可以实现多个接口,当创建一个此类的对象之后,通过引用这个对象的对象变量可以访问其所有的公有方法(包括自身的公有方法以及由接口定义的公有方法

以)。在这种情况下,根本分不清哪些方法是由接口定义的,哪些是由类自己定义的。C#提供了一种“显式接口”实现机制,可以区分开这两种情况,一个示例代码如下:

interface  IMyInterface

{

void func();

}

public class  A:IMyInterface

{

void IMyInterface.func()

{

//……

}

public void func2()

{

//……

}

}

请注意在方法 func前以粗体突出显示的接口名称,这就是  C#对接口 IMyInterface的显式实现方式。

当类 A显式实现接口  IMyInterface之后,只能以下面这种方式访问接口定义的方法:

IMyInterface  a = new  A();

a.func();

以下代码将不能通过编译:

A  a = new  A();

a.func();

由此得到一个结论:

如果一个类显式实现某个接口,则只能以此接口类型的变量为媒介调用此接口所定义的方法,而不允许通过类的对象变量直接调用。

或者这样说:

被显式实现的接口方法只能通过接口实例访问,而不能通过类实例直接访问。

时间: 2024-10-22 09:08:06

五、抽象基类与接口的相关文章

C#编程语言与面向对象——抽象基类与接口

在一个类前加“abstract”关键字,此类就成为抽象类. 对应的,在一个方法前加“abstract”关键字,此方法就成为抽象方法. abstract class Fruit //抽象类 { public abstract void GrowInArea();//抽象方法 } 注意抽象方法不能又实现代码,在方法名后直接跟一个分号. 抽象类专用于派生出子类,子类必须实现抽象类中所生命的方法.否子子类仍是抽象类. 抽象类一般用于表达一种比较抽象的事物,比如说“水果”,而抽象方法则说明此抽象类应该具有

6、面向对象以及winform的简单运用(抽象基类与接口)

抽象类与抽象方法 1.书写规范: 在类前面加上abstract关键字,就成为了抽象类:在一个方法前面加上abstract关键字,就成为了抽象方法(抽象方法不能有实现方法,直接在后面加分号) 例: abstract class Chouxiang //抽象类 { public abstract void fangfa(); //抽象方法 } 2.抽象类的注意事项: 1)当一个类变为抽象类之后就不能作为对象来使用了,无法new出来 2)抽象方法必须放在抽象类里面(但抽象类中不一定有抽象方法) 3)没

抽象基类与接口

5.1抽象类与抽象方法 在一个类前面加上“abstract”关键字,此类就成为了抽象类. 对应地,一个方法类前面加上“abstract”关键字,此方法就成为了抽象方法. 注意抽象方法不能有实现代码,在函数名后直接跟一个分号. 抽象类专用于派生出子类,子类必须实现抽象类所声明的抽象方法,否则,子类仍是抽 象类. 抽象类一般用于表达一种比较抽象的事物,比如前面所说的“水果”,而抽象方法则说 明此抽象类应该具有的某种性质,比如 Fruit类中有一个抽象方法  GrowInArea(),说明水果 一定有

类,抽象基类,接口类三者间的区别与联系(C++)

联系很明显,三个都是‘类’,如果读者对类的概念不清楚,可以参照wid的博文http://www.cnblogs.com/mr-wid/archive/2013/02/18/2916309.html. 下面着重解释一下区别,但此文仅是个人理解,如果觉得我说的不对的地方,还请赐教. (1)结构上的区别: 普通类:数据+方法+实现 抽象类:数据+方法(一定包含虚方法n>=1)+部分方法的实现 接口类:方法(纯虚方法) (2)概念上的区别: 普通的类和另外两个的区别很明显,普通类就是猫狗之类的,而抽象类

12-14面向对象--抽象基类、接口、委托

一.抽象类与抽象方法 1.在一个类前面加上abstract关键字,此类就成为了抽象类. 1)当一个类变成抽象类时,就不能作为一个对象使用了,也就是说不能创建新对象,不能new初始化. 2)抽象方法只是一个方法,不能写方法. 3)当一个类继承的是抽象类时,必须要把抽象类的抽象方法重写(override)才可以实现方法. 4)抽象方法必须放在抽象类里面才能使用,抽象方法是在抽象子类中实现的,也就是说抽象子类实现抽象父类所有的抽象方法. 5)有抽象方法的一定是抽象类:有抽象类但不一定有抽象方法. 6)

python(七):元类与抽象基类

一.实例创建 在创建实例时,调用__new__方法和__init__方法,这两个方法在没有定义时,是自动调用了object来实现的.python3默认创建的类是继承了object. class A(object): def __init__(self, *args, **kwargs): self.name, self.age, self.gender = args[:3] def __new__(cls, *args, **kwargs): print("__new__ has called.

Python 接口:从协议到抽象基类

抽象基类的常见用途:实现接口时作为超类使用.然后,说明抽象基类如何检查具体子类是否符合接口定义,以及如何使用注册机制声明一个类实现了某个接口,而不进行子类化操作.最后,说明如何让抽象基类自动“识别”任何符合接口的类——不进行子类化或注册. Python文化中的接口和协议 接口在动态类型语言中是怎么运作的呢?首先,基本的事实是,Python语言没有 interface 关键字,而且除了抽象基类,每个类都有接口:类实现或继承的公开属性(方法或数据属性),包括特殊方法,如__getitem__ 或 _

定义接口或者抽象基类

你想定义一个接口或抽象类,并且通过执行类型检查来确保子类实现了某些特定的方法. 解决方案: 使用 abc 模块可以很轻松的定义抽象基类 from abc import ABCMeta, abstractmethod class IStream(metaclass=ABCMeta): @abstractmethod def read(self, maxbytes=-1): pass @abstractmethod def write(self, data): pass 抽象类的一个特点是它不能直接

C++编程实践: 抽象基类

本实例来自<C++ Primer Plus>(第六版) 第十三章 题目要求: 假设你正在开发一个图形程序,该程序会显示圆和椭圆等,需要考虑: 椭圆要包含椭圆中心坐标,半长轴,半短轴以及方向角的数据.圆要实现圆心坐标,半径等数据. 椭圆要包含移动,旋转一定角度,计算面积和缩放等方法,但是圆不需要旋转. 设计思路: 虽然圆也是一种椭圆的特殊形势,但是设计成由圆类继承椭圆类显然是十分笨拙的.比较好的办法是涉及一个基类BaseEllipse,圆和椭圆都继承此基类.这样便可以使用指针数组同时管理Circ