嗨,伙计们,我是 c# 的新手,我从微软那里找到了以下答案,建议使用接口和抽象。
如果您预期创建组件的多个版本,请创建一个抽象类。抽象类提供了一种简单易行的方式来对组件进行版本控制。通过更新基类,所有继承类都会随着更改而自动更新。另一方面,接口一旦创建就不能更改。如果需要新版本的接口,则必须创建一个全新的接口。
你是什么意思创建组件的多个版本。你能详细说明更多提供的例子吗?
拥有共享某种行为和/或属性的类似类是您使用基类的时候。典型的例子之一是形状。你可以这样:
基础抽象类 - FourSidedShape
派生类 - 矩形
派生类 - 平行四边形
您的派生类还可以添加他们想要的不属于基类的任何独特行为。
注意:抽象类是不能直接实例化的。您必须使用派生类之一。
这确实应该是两个问题,但我会同时回答它们。
第二个第一:可空类型的用法是:
decimal? priceFromDb = datarow.Field<decimal?>("price");
在这种情况下,您声明的类型将包含十进制值,但可能为 null,因为在这种情况下,它来自数据库,并且基础字段可能为 null。声明可空类型的正确方法是?
在类型名称的末尾使用 。然后,当您想使用有问题的值时,您可以执行以下操作:
if (priceFromDb.HasValue)
{
Console.WriteLine("The price is {0}.", priceFromDb.Value);
}
第一个问题:在 C# 中使用接口来确保类或结构实现您需要的某些关键功能。它们通常只包含少数方法,通常不超过一两个,其想法是,一旦您创建了一个已发布的接口,它就不会改变。另一方面,抽象类使您能够强制类实现您需要的方法,并为它们提供通用功能,如果您将来对抽象类进行更改,例如,添加更多通用特征,继承类自动获取特征。使用抽象类并不是发布重大更改的许可,它只是一种将通用特性组合到类中的更简洁功能的方法。
如果您查看 .Net 框架,您会发现大多数接口(IEquatable、IDisposable、IComparable)通常用于对对象强制执行行为,而不是对其整个结构。
例如,考虑一个抽象类车辆:
abstract class Vehicle
{
public int NumWheels { get; set; }
public string Name { get; set; }
public abstract void Drive();
public override string ToString()
{
return "I am a vehicle!";
}
}
您可以创建一个继承自 Vehicle 的汽车对象,并且需要实现Drive()
,但将免费获得这两个属性。如果需要,您的继承类 car 也可以重载,或者保持原样:NumWheels
Name
ToString()
public class Car : Vehicle
{
public override void Drive()
{
// your implementation here
}
public override string ToString()
{
return "I am a car!";
}
}
可能“抽象类和接口之间的区别”是 .Net 世界中最常见的问题。我将解释理论上的差异,然后是代码片段。
根据我的理论,抽象类和接口之间基本上有5个区别,如下所示:-
一个类可以实现任意数量的接口,但一个子类最多只能使用一个抽象类。
抽象类可以有非抽象方法(具体方法),而在接口的情况下,所有方法都必须是抽象的。
抽象类可以声明或使用任何变量,而接口不允许这样做。因此以下代码将无法编译:-
接口测试接口
{
int x = 4; // Filed Declaration in Interface
void getMethod();
string getName();
}
抽象类 TestAbstractClass
{
int i = 4;
int k = 3;
public abstract void getClassName();
}
它将生成编译时错误:-
错误 1 接口不能包含字段。
所以我们需要省略字段声明才能正确编译代码。
接口测试接口
{
void getMethod();
string getName();
}
抽象类 TestAbstractClass
{
int i = 4;
int k = 3;
public abstract void getClassName();
}
上面的代码可以正确编译,因为接口中没有字段声明。
4.抽象类可以有构造函数声明,而接口不能有。
所以以下代码将无法编译:-
接口测试接口 {
// Constructor Declaration
public TestInterface()
{
void getMethod();
string getName();
}
}
抽象类 TestAbstractClass
{
public TestAbstractClass()
{
int i = 4;
int k = 3;
public abstract void getClassName();
}
}
上面的代码将生成一个编译时错误:-
错误 1 接口不能包含构造函数
所以我们需要从接口中省略构造函数声明才能编译我们的代码。
以下代码完美编译:-
接口测试接口 {
void getMethod();
string getName();
}
抽象类 TestAbstractClass {
public TestAbstractClass()
{
int i = 4;
int k = 3;
public abstract void getClassName();
}
}
5.一个抽象类允许对其所有成员声明具有所有访问修饰符,而在接口中我们不能声明任何访问修饰符(包括公共),因为接口的所有成员都是隐式公共的。
注意:这里我说的是接口成员的访问说明符,而不是接口。
以下代码将更好地解释它:-
将提供访问说明符设置为 Public 是完全合法的(记住只允许 public)
公共接口测试接口
{
void getMethod();
string getName();
}
上面的代码编译完美。
不允许为接口的成员提供任何访问说明符。
接口测试接口
{
public void getMethod();
public string getName();
}
上面的代码将生成一个编译时错误:-
错误 1 修饰符“public”对此项无效。
但是声明接口的最好方法是避免接口上的访问说明符以及接口的成员。
接口测试
{
void getMethod();
string getName();
}