[英]Can method inheritated from interface return another type that in interface?
[英]How do I define the return type of an interface method to be another interface?
我是接口和抽象类的新手。 我想创建几个接口来为购物车系统的对象定义核心方法和变量。 然后我想创建实现核心功能的抽象类。 这个想法是它们可以被其他类以稍微不同的方式用于不同的项目。
这是我的(精简)界面:
public interface ICart
{
...
List<ICartItem> CartItems { get; set; }
}
public interface ICartItem
{
int ProductId { get; set; }
int Quantity { get; set; }
}
这是我实现ICart的抽象购物车class(同样,只显示相关行):
public abstract class Cart : ICart
{
private List<CartItem> _cartItems = new List<CartItem>();
public List<CartItem> CartItems
{
get
{
return _cartItems;
}
}
}
还有我的实现 ICartItem 的 CartItem class:
public abstract class CartItem : ICartItem
{
...
}
当我尝试编译这些类时,我收到一条错误消息:“Cart”没有实现接口成员“CartItems”。 “Cart.CartItems”无法实现“ICart.CartItems”,因为它没有 System.Collections.Generic.List<ICartItem> 的匹配返回类型。
我认为这里的想法是接口可以由许多类实现,这些类以不同的方式执行核心功能并添加新方法等。为什么我的接口需要知道 class 实际使用的是什么,只要因为 class 实际上正确实现了接口?
您需要在 C# 2 中使用 generics 来实现:
public interface ICart<T> where T : ICartItem
{
// ...
List<T> CartItems { get; set; }
}
public abstract class Cart : ICart<CartItem>
{
// ...
public List<CartItem> CartItems { get; set; }
}
在您的抽象 class 中,您应该定义 CartItems 属性的返回类型为List<ICartItem>
类型。
但是,如果您真的希望该属性是List<CartItem>
类型,您可以这样做:
public interface ICart<TCartItem> where TCartItem : ICartItem
{
List<TCartItem> CartItems { get; set; }
}
public interface ICartItem
{
}
public abstract class Cart : ICart<CartItem>
{
public List<CartItem> { get; set; }
}
public abstract class CartItem : ICartItem
{
}
这是一个反/协方差的问题。
进行此编译需要 2 处更改。
1) 去掉接口属性上的“set”选项。 (它只是实现一个 get; 属性,无论如何,这是最有意义的)
2) 将购物车更改为:
public abstract class Cart : ICart
{
private List<CartItem> _cartItems = new List<CartItem>();
public List<ICartItem> CartItems
{ ...
我还强烈建议您更改界面以公开 IList 而不是 List。 设计指南(和 FxCop)建议不要在公共界面中公开 List。 List 是一个实现细节 - IList 是适当的接口/返回类型。
接口是一种协议。 如果您愿意,您与使用您的 class 的任何人之间的合同。 通过告诉人们您正在实现 ICart 接口,您向他们保证接口中的所有方法都存在于您的 class 上。 因此,您的所有方法都必须与接口方法的签名相匹配。
为了返回实现ICartItem 的项目列表,您需要按照 DrJokepu 的建议使用 generics。 这告诉大家,该接口只提供了一个实现 ICartItem 的对象列表,而不是具体的 ICartItem。
public interface ICart<T> where T : ICartItem
{
List<T> CartItems { get; set; }
}
ICart 为 CartItems 指定了一个 getter 和 setter,但您的实现只有一个 get。
有两种方法可以做到这一点。 您可以使用 generics 或显式实现接口成员。
Generics
public interface ICart<TCartItem> where TCartItem : ICartItem
{
...
List<TCartItem> CartItems { get; set; }
}
public interface ICartItem
{
int ProductId { get; set; }
int Quantity { get; set; }
}
public abstract class Cart : ICart<CartItem>
{
private List<CartItem> _cartItems = new List<CartItem>();
public List<CartItem> CartItems
{
get
{
return _cartItems;
}
}
}
public abstract class CartItem : ICartItem
{
...
}
显式实现的成员
public interface ICart
{
...
List<ICartItem> CartItems { get; set; }
}
public interface ICartItem
{
int ProductId { get; set; }
int Quantity { get; set; }
}
public abstract class Cart : ICart
{
private List<CartItem> _cartItems = new List<CartItem>();
List<ICartItem> ICart.CartItems
{
get
{
return CartItems;
}
}
public List<CartItem> CartItems
{
get
{
return _cartItems;
}
}
}
public abstract class CartItem : ICartItem
{
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.