在其中一篇 MSDN 文章中提到以下行
接口无法在以后的版本中指定新成员 抽象类可以根据需要添加成员以支持其他成员 功能。
我从 here 中选择了这句话。您可以阅读第3段中的相同句子。
我有一个困惑,提前抱歉,以防我遗失了什么。
一旦声明了Abstaract类或接口,然后任何Derived类继承这些方法,在任何一种情况下,都应该重写所有方法。否则将出现编译错误。
您的意见?
答案 0 :(得分:4)
一旦声明了Abstaract类或接口,然后任何Derived类继承这些方法,在任何一种情况下,都应该重写所有方法。否则将出现编译错误。
不,对于抽象类,只需要覆盖 abstract 方法。您可以添加非抽象方法,没有错误。
例如,版本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的代码同时重建,这通常不是问题,无论是接口还是抽象类。如果要向接口添加方法,可以这样做,因为可以同时升级所有实现。
当你不控制整个代码库时,你需要小心。
答案 1 :(得分:1)
实现接口的类必须实现接口中定义的所有方法和属性。
从Abstract类继承时,必须实现/覆盖所有Abstract成员,但是任何非抽象成员都将继承,就像从具体类继承一样。
答案 2 :(得分:0)
实现接口会强制您覆盖其方法 - 继承一个类然后会给您一个选择。只需要覆盖抽象方法。 MSDN摘录指出,当所有实现者都需要实现添加的方法时,严格的接口契约的价格在以后证明是昂贵的。通过使用虚拟方法的父类,您可以稍后决定是否需要专业化。
答案 3 :(得分:0)
从Interfaces继承时,必须实现该接口的所有成员。但您可以根据自己的需要扩展界面。您还可以继承多个接口。有效示例:
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();
}
}
最后,也是最有力的,你可以将一个抽象基类和你想要的接口混合在一起......所以,如果我保留抽象类Person,来自例2,接口IPersonDBContext来自例1,我可以做到这一点:
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.
}
}
希望有帮助...