Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在抽象类和接口中有相同的字段名可以吗?_C#_Oop_Inheritance_Interface - Fatal编程技术网

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; }
        }
    }