接触面向对象也有一段时间了,可是理解一直特别地浅。要用的时候才知道无从下手。最近又将面向对象相关的书籍看了看,一些概念比如:封装、继承和多态有了一些认识,但是还有一些就让我焦头烂额了,比如:委托。这里我整理了一些关于抽象类和接口的知识,其中以一个大家都非常熟悉的例子进行讲解(动物)。
1.抽象类
现实世界中猫和狗都叫做动物,我们可以实实在在地找到一只猫,也可以实实在在地找到一只狗。但是却找不到一个实体是对应于动物的。很简单因为动物是一个抽象的名词。C#中把类和方法声明为abstract,即抽象类和抽象方法。而VB.NET中使用MustInherit和MustOverride修饰符。
C#:
abstract class Animal
(
......
protected abstract string getShoutSound();
)
VB.NET
Public MustInherit Class Animal
.....
protected MustOverride Function getShoutSound() As String
End Class
注意点:
第一,抽象类不能实例化,刚才就说过‘动物’实例化没有意义;第二,抽象方法是必须被子类重写的方法,其实抽象方法可以被看做是没有实现体的虚方法;第三,如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他的一般方法。
2.接口
比如:现在我们有猫一个类。有特异功能的叮当猫除了继承猫一般功能“叫”以外,还具有”变出东西“的特殊功能。这时就需要用到接口的知识了。
接口是把隐式公共方法和属性组合起来,以封装特定功能的一个集合。一旦类实现了接口,类就可以支持接口所指定的所有属性和成员。声明接口在语法上与声明抽象类完全相同,但不允许提供接口中任何成员的执行方式。所以接口不能实例化,不能有构造方法和字段,不能有修饰符,比如:public、private等;实现接口的类就必须要实现接口中所有的方法和属性。
C#:
Interface Ichange '定义接口
{
string ChangeThing(string thing);
}
Class MachineCat:Cat,Ichange '继承父类Cat和实现接口
{
public MachineCat() '重载构造函数,这里VB.NET和C#很不同。
:base()
{
}
public MachineCat(string name)
:base(name)
{
}
public string ChangeThing(string thing)
{
return "我有万能口袋,我可变出" + thing;
}
}
private void button1_Click(object sender,EventArgs e)
{
MachineCat mcat=new MachineCat("叮当");
MessageBox.Show(cmat.ChangeThing("各种各样的东西!"));
}
VB.NET:
Public Interface IChange '定义接口
Function ChangeThing(ByVal thing As String) As String
End Interface
Public Class MachineCat '继承父类Cat
Inherits Cat
Public overloads Sub New() '重载构造函数
MyBase.New()
End Sub
Public overloads Sub New(ByVal name As String)
MyBase.New(name)
End Sub
End Class
Public Class MachineCat :Implements IChange '实现接口
Public Function ChangeThing(ByVal thing As String ) As String Implements IChange.ChangeThings()
return "我有万能口袋,我可变出"+ thing;
End Function
End Class
Private Sub buttton1_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
Dim mcat As MachineCat =New MachineCat("叮当")
MessageBox(mcat.ChangeThing("各种各样的东西!"))
End Sub
3.两者的对比
从表象上看,抽象类可以给出一些成员的实现,接口却不包含成员的实现,抽象类的抽象成员可被子类部分实现,接口的成员需要实现类完全实现,一个类只能继承一个抽象类,但可以实现多个接口等。
还有三点帮助区分抽象类和接口:第一,类是对象的抽象,抽象类是类的抽象,接口是对行为的抽象。第二,如果行为超越了不同类的对象,可使用接口;对于一些相似的类对象,用继承抽象类。第三,从设计角度看,抽象类是子类中发现了公共的东西,泛化出父类,然后子类继承父类,而接口是根本不知子类的存在,方法如何实现还不确认,预先定义。抽象类是自底向上抽象出来的,而接口是自顶向下设计出来的。