C# 在抽象类和接口中有相同的字段名可以吗?
我正在创建一些类,现在我需要征求您的意见。让我们想象一下这样的情况: 我们有一个抽象类C# 在抽象类和接口中有相同的字段名可以吗?,c#,oop,inheritance,interface,C#,Oop,Inheritance,Interface,我正在创建一些类,现在我需要征求您的意见。让我们想象一下这样的情况: 我们有一个抽象类A: abstract class A { public int Id {get; set;} } 我们有三个类来实现它B,C和D: class B : A { public List<string> Comments {get; set;} public List<string> Categories {get; set;} } class C : A { publ
A
:
abstract class A {
public int Id {get; set;}
}
我们有三个类来实现它B
,C
和D
:
class B : A {
public List<string> Comments {get; set;}
public List<string> Categories {get; set;}
}
class C : A {
public List<string> Categories {get; set;}
}
class D : A {
public List<string> Comments {get; set;}
}
B类:A类{
公共列表注释{get;set;}
公共列表类别{get;set;}
}
丙类:甲{
公共列表类别{get;set;}
}
D类:A{
公共列表注释{get;set;}
}
正如您所看到的,一些属性是公共的,我想将它们提取到另一个类/接口。因此理论上我可以创建以下接口:
interface IWithCategories {
List<string> Categories {get; set;}
}
interface IWithComments {
List<string> Comments {get; set;}
}
接口类别{
列表类别{get;set;}
}
接口IWithComments{
列出注释{get;set;}
}
让B
、C
和D
实现他们所需要的。问题是,当我使用IWithCategories
时,我还需要A
中的属性
解决这个问题的好办法是什么
我的想法如下:
A
提取接口,称为IA
<代码>A当然将实现IA
接口IA{
int Id{get;set;}
}
抽象A类:IA{
公共int Id{get;set;}
}IWithComments
和IWithCategories
将扩展IA
:
接口类别:IA{
列表类别{get;set;}
}
接口IWithComments:IA{
列出注释{get;set;}
}B
,C
和D
可以实现它们:
B类:A、IWithCategories、IWithComments{
公共列表注释{get;set;}
公共列表类别{get;set;}
}
C类:A类,I类{
公共列表类别{get;set;}
}
D类:A{
公共列表注释{get;set;}
}B
、C
和D
不需要扩展抽象类A
,但它有一些实现,可以在所有类之间共享,比如equals、string和一些受保护的方法
这种做法是否可以接受
编辑:
我正在使用Xamarin编写一个iOS应用程序,一开始我只有
A
、B
、C
和D
。我遇到过这样一种情况,我正在创建一个ViewController,它应该用于所有有注释的类,这就是我想到提取接口的时候。但是,我还需要调用一个web服务,我需要在a
上声明Id
,现在我正在考虑如何处理这个问题。希望能有帮助。好吧,为什么接口需要setter,我假设它们不需要。接口是否需要公开List
而不是IList
,我假设不需要。然后就有了这些接口定义
public interface IWithCategories {
IList<string> Categories { get; }
}
public interface IWithComments {
IList<string> Comments { get; }
}
A
的继承人如何实现IWithCategories
、IWithComments
和Id
属性,不能在接口定义的合同中定义
但是,您可能会设想这样一个实现:
public class B : A
{
private readonly int id;
private readonly List<string> categories;
private readonly List<string> comments;
public B(
int id,
IEnumerable<string> categories
IEnumerable<string> comments)
{
this.id = id;
this.categories = (categories ?? Enumerable.Empty<string>()).ToList();
this.comments = (comments ?? Enumerable.Empty<string>()).ToList();
}
public override int Id
{
get { return this.id; }
}
public override IList<string> Categories
{
get { return this.categories; }
}
public override IList<string> Comments
{
get { return this.comments; }
}
}
公共B类:A
{
私有只读int-id;
私有只读列表类别;
私人只读列表注释;
公共B(
int id,
可数范畴
(可数评论)
{
this.id=id;
this.categories=(categories??Enumerable.Empty()).ToList();
this.comments=(comments??Enumerable.Empty()).ToList();
}
公共覆盖int-Id
{
获取{返回this.id;}
}
公共分类
{
获取{返回this.categories;}
}
公众评论
{
获取{返回this.comments;}
}
}
关于品脱1:
如果在抽象类唯一的情况下,IA
接口有多个实现,这是很好的。那么就没有理由创建额外的抽象层了。特别是当抽象类的实现部分基于该方法时
关于第2点:
IWithCategories:IA
和IWithComments:IA
你可以租一辆车。请注意,命名可以反映更多的.NET约定ICategorizable
和ICommentable
。这些不是有效的词语,但表达了想法
还要记住,接口应该提供一些功能。如Jodreli所写的那样,使用setter将打开您的API
关于第3点:
在这一点上,很难给出建议,因为您的示例非常抽象和模糊。最终的实现可能会因B、C和D类的原因而有所不同
这里有一个提示,您应该并且也要确保类B、C和D确实是概念的好例子 这是可以的,但是如果你想要一个不同的实现,你可以显式地实现这个接口。我一般都可以接受,但是知道你对这个结构的目标会有很大帮助。更新了我的帖子。希望能有帮助。你所说的“促进写作”到底是什么意思
public class B : A
{
private readonly int id;
private readonly List<string> categories;
private readonly List<string> comments;
public B(
int id,
IEnumerable<string> categories
IEnumerable<string> comments)
{
this.id = id;
this.categories = (categories ?? Enumerable.Empty<string>()).ToList();
this.comments = (comments ?? Enumerable.Empty<string>()).ToList();
}
public override int Id
{
get { return this.id; }
}
public override IList<string> Categories
{
get { return this.categories; }
}
public override IList<string> Comments
{
get { return this.comments; }
}
}