可能的重复:
接口与抽象类(一般 OO)
在MSDN文章之一中提到了以下行
接口不能在以后的版本中指定新成员,而抽象类可以根据需要添加成员以支持附加功能。
我从这里挑选了这句话。您可以阅读第 3 段中的相同句子。
我有一个困惑,提前抱歉,以防我遗漏了什么。
一旦声明了抽象类或接口,然后任何派生类都继承了这些方法,在任何一种情况下,所有方法都应该被覆盖。否则会出现编译错误。
你的评论?
可能的重复:
接口与抽象类(一般 OO)
在MSDN文章之一中提到了以下行
接口不能在以后的版本中指定新成员,而抽象类可以根据需要添加成员以支持附加功能。
我从这里挑选了这句话。您可以阅读第 3 段中的相同句子。
我有一个困惑,提前抱歉,以防我遗漏了什么。
一旦声明了抽象类或接口,然后任何派生类都继承了这些方法,在任何一种情况下,所有方法都应该被覆盖。否则会出现编译错误。
你的评论?
一旦声明了抽象类或接口,然后任何派生类都继承了这些方法,在任何一种情况下,所有方法都应该被覆盖。否则会出现编译错误。
不,对于抽象类,只需要重写抽象方法。您可以添加没有错误的非抽象方法。
例如,版本 1:
public abstract class FooBase
{
public abstract void Bar();
}
public class FooImpl : FooBase
{
public override void Bar() {}
}
现在在版本 2中引入一个新的非抽象方法:FooBase
public abstract class FooBase
{
public abstract void Bar();
public void NewMethod() {}
}
……没有问题。
请注意,对于公司内部代码,将同时重建所有将使用 API 的代码,这通常根本不是问题,无论是接口还是抽象类。如果您想向接口添加方法,您可以这样做,因为您可以同时升级所有实现。
确实,当您无法控制整个代码库时,您需要小心。
实现接口的类必须实现接口中定义的所有方法和属性。
从抽象类继承时,您必须实现/覆盖所有抽象成员,但任何非抽象成员都将被继承,就像从具体类继承时一样。
从接口继承时,必须实现该接口的所有成员。但是您可以根据需要扩展界面。您还可以继承多个接口。有效示例:
public interface IPerson
{
string FullName { get; set; }
string SSN { get; set; }
}
public interface IPersonDBContext
{
void Save(IPerson person);
}
public class PersonData : IPerson, IPersonDBContext
{
// Implements IPerson FullName
public string FullName { get; set; }
// Implements IPerson SSN
public string SSN { get; set; }
// Implements IPersonDBContext Save()
public void Save(IPerson person)
{
// Code to save the IPerson instance to the DB...
}
// Added method, not included in any interface...
public void Validate(IPerson person)
{
// Code to validate the IPerson instance...
}
}
现在,对于抽象类,您可以包含可以继承的具体方法,也可以指定一些必须重写的方法。但是,请注意,您不能拥有多个基类(并且抽象类仍然是一个类......)所以您不能像接口那样混合两个抽象类。例子:
public abstract class Person
{
public string FullName { get; set; }
public string SSN { get; set; }
public abstract void Save();
}
public class PersonData : Person
{
// Implements Abstract Person Save() Method
public override void Save()
{
// Save logic here...
}
// Non-inherited member...
public void Validate()
{
// Access properties of the base class (Abstract Person)
this.FullName.ToString();
this.SSN.ToString();
}
}
最后,也是最强大的,您可以将单个抽象基类与任意数量的接口混合在一起......所以,如果我保留示例 2 中的抽象类 Person 和示例 1 中的接口 IPersonDBContext,我可以这样做:
public class PersonData : Person, IPersonDBContext
{
// Implements Abstract Person Save() Method
public override void Validate()
{
// Access properties of the base class (Abstract Person)
this.FullName.ToString();
this.SSN.ToString();
}
// Inplmenets IPersonDBContext Save()
public void Save(Person person)
{
// Save logic here...
}
// Non-inhereted method
public void Clone(Person person)
{
// Logic to make a member-wise clone.
}
}
希望有帮助...
实现一个接口会迫使你重写它的方法——然而继承一个类会给你一个选择。只有抽象方法需要被覆盖。MSDN 摘录指出,当所有实现者都需要实现添加的方法时,严格接口契约的价格可能会在以后证明是昂贵的。使用带有虚拟方法的父类可以让您稍后决定是否需要专门化。