【C#】抽象类和接口的区别

4 篇文章 0 订阅
namespace cs {
    public partial class Program {
        public abstract class A {
            // static members
            // abstract and virtual modifiers are not allowed on fields
            public static int P1SF;
            protected internal static int PISF;
            internal static int InSF;
            protected static int P2SF;
            private static int P3SF;
            // You cannot use abstract / virtual modifier on static properties of an abstract class
            public static int P1S_P { get; set; }
            protected internal static int PIS_P { get; set; }
            internal static int InS_P { get; set; }
            protected static int P2S_P { get; set; }
            private static int P3S_P { get; set; }
            // You cannot use abstract / virtual modifier on static methods of an abstract class
            public static void P1S_M() { }
            protected internal static void PIS_M() { }
            internal static void InS_M() { }
            protected static void P2S_M() { }
            private static void P3S_M() { }
            // instance members
            // abstract and virtual modifiers are not allowed on fields
            public int P1_F;
            protected internal int PI_F;
            internal int In_F;
            protected int P2_F;
            private int P3_F;
            public int P1__P { get; set; }
            protected internal int PI__P { get; set; }
            internal int In__P { get; set; }
            protected int P2__P { get; set; }
            private int P3__P { get; set; }
            public abstract int P1_AP { get; set; }
            protected internal abstract int PI_AP { get; set; }
            internal abstract int In_AP { get; set; }
            protected abstract int P2_AP { get; set; }
            // abstract members cannot be private
            public virtual int P1_VP { get; set; }
            protected internal virtual int PI_VP { get; set; }
            internal virtual int In_VP { get; set; }
            protected virtual int P2_VP { get; set; }
            // virtual members cannot be private
            public void P1__M() { }
            protected internal void PI__M() { }
            internal void In__M() { }
            protected void P2__M() { }
            private void P3__M() { }
            public abstract void P1_AM();
            protected internal abstract void PI_AM();
            internal abstract void In_AM();
            protected abstract void P2_AM();
            // abstract members cannot be private
            public virtual void P1_VM() { }
            protected internal virtual void PI_VM() { }
            internal virtual void In_VM() { }
            protected virtual void P2_VM() { }
            // virtual members cannot be private
        }
        public interface I {
            // static members
            // abstract and virtual modifiers are not allowed on fields
            public static int P1SF;
            protected internal static int PISF;
            internal static int InSF;
            protected static int P2SF;
            private static int P3SF;
            // In C# 11 (.NET 7), you can use abstract / virtual modifier on static properties of an interface
            public static int P1S_P { get; set; }
            protected internal static int PIS_P { get; set; }
            internal static int InS_P { get; set; }
            protected static int P2S_P { get; set; }
            private static int P3S_P { get; set; }
            public static abstract int P1SAP { get; set; }
            protected internal static abstract int PISAP { get; set; }
            internal static abstract int InSAP { get; set; }
            protected static abstract int P2SAP { get; set; }
            public static virtual int P1SVP { get; set; }
            protected internal static virtual int PISVP { get; set; }
            internal static virtual int InSVP { get; set; }
            protected static virtual int P2SVP { get; set; }
            // In C# 11 (.NET 7), you can use abstract / virtual modifier on static methods of an interface
            public static void P1S_M() { }
            protected internal static void PIS_M() { }
            internal static void InS_M() { }
            protected static void P2S_M() { }
            private static void P3S_M() { }
            public static abstract void P1SAM();
            protected internal static abstract void PISAM();
            internal static abstract void InSAM();
            protected static abstract void P2SAM();
            public static virtual void P1SVM() { }
            protected internal static virtual void PISVM() { }
            internal static virtual void InSVM() { }
            protected static virtual void P2SVM() { }
            // instance members
            // interfaces cannot have instance fields
            public int P1__P { get; set; }
            protected internal int PI__P { get; set; }
            internal int In__P { get; set; }
            protected int P2__P { get; set; }
            private int P3__P { get { return 0; } set { } }
            public abstract int P1_AP { get; set; }
            protected internal abstract int PI_AP { get; set; }
            internal abstract int In_AP { get; set; }
            protected abstract int P2_AP { get; set; }
            // abstract members cannot be private
            public virtual int P1_VP { get { return 0; } set { } }
            protected internal virtual int PI_VP { get { return 0; } set { } }
            internal virtual int In_VP { get { return 0; } set { } }
            protected virtual int P2_VP { get { return 0; } set { } }
            // virtual members cannot be private
            public void P1__M() { }
            protected internal void PI__M() { }
            internal void In__M() { }
            protected void P2__M() { }
            private void P3__M() { }
            public abstract void P1_AM();
            protected internal abstract void PI_AM();
            internal abstract void In_AM();
            protected abstract void P2_AM();
            // abstract members cannot be private
            public virtual void P1_VM() { }
            protected internal virtual void PI_VM() { }
            internal virtual void In_VM() { }
            protected virtual void P2_VM() { }
            // virtual members cannot be private
        }
        public class C : A {
            public override int P1_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            protected override int P2_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            protected internal override int PI_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            internal override int In_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            public override void P1_AM() => throw new NotImplementedException();
            protected override void P2_AM() => throw new NotImplementedException();
            protected internal override void PI_AM() => throw new NotImplementedException();
            internal override void In_AM() => throw new NotImplementedException();
        }
        public class D : I {
            static int I.P1SAP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            static int I.PISAP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            static int I.InSAP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            static int I.P2SAP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.P1__P { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.PI__P { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.In__P { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.P2__P { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.P1_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.PI_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.In_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.P2_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            static void I.InSAM() => throw new NotImplementedException();
            static void I.P1SAM() => throw new NotImplementedException();
            static void I.P2SAM() => throw new NotImplementedException();
            static void I.PISAM() => throw new NotImplementedException();
            void I.In_AM() => throw new NotImplementedException();
            void I.P1_AM() => throw new NotImplementedException();
            void I.P2_AM() => throw new NotImplementedException();
            void I.PI_AM() => throw new NotImplementedException();
        }
        public class E : A, I {
            public override int P1_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            protected override int P2_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            protected internal override int PI_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            internal override int In_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            public override void P1_AM() => throw new NotImplementedException();
            protected override void P2_AM() => throw new NotImplementedException();
            protected internal override void PI_AM() => throw new NotImplementedException();
            internal override void In_AM() => throw new NotImplementedException();
            static int I.P1SAP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            static int I.PISAP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            static int I.InSAP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            static int I.P2SAP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.PI__P { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.In__P { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.P2__P { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.PI_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.In_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            int I.P2_AP { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            static void I.P1SAM() => throw new NotImplementedException();
            static void I.InSAM() => throw new NotImplementedException();
            static void I.P2SAM() => throw new NotImplementedException();
            static void I.PISAM() => throw new NotImplementedException();
            void I.In_AM() => throw new NotImplementedException();
            void I.P2_AM() => throw new NotImplementedException();
            void I.PI_AM() => throw new NotImplementedException();
        }
        public static void Main(string[] args) {
            C c = new();
            D d = new();
            E e = new();
            Console.WriteLine(c);
            Console.WriteLine(d);
            Console.WriteLine(e);
        }
    }
}

相同点

  • abstract 和 virtual 关键字均不可修饰字段,但可以修饰属性和方法。
  • abstract 和 virtual 成员不能是 private 访问控制。
  • 对于每个成员,abstract 和 virtual 关键字只能使用一个,或者都不使用。
  • 均不可实例化。

不同点

  • abstract 和 virtual 关键字均不可修饰抽象类的静态属性和方法,但自 C# 11 起,可以修饰接口的静态属性和方法。故而,接口的非 private 静态抽象属性和非 private 静态抽象方法均必须实现,否则编译不通过。
  • 在抽象类中,不被 abstract 修饰但省略了方法体的方法会令编译报错(要求添加 abstract,extern 或 partial 关键字)。而在接口中,不被 abstract 修饰但省略了方法体(不具有默认实现)的方法本身不会令编译报错,但必须提供这些方法的实现。
  • 在抽象类中,实现 abstract 属性和 abstract 方法时,需要使用 override 关键字。但在接口中,实现属性和方法时,不需要使用 override 关键字,即便该方法被 abstract 修饰。
  • 抽象类可以含有实例字段,但接口不可含有实例字段。
  • 抽象类的非 private 一般实例属性(非 abstract 且非 virtual)不要求必须实现,而接口的非 private 一般实例属性必须提供实现,否则编译不通过。
  • 抽象类的 private 一般实例属性及 virtual 的实例属性可以使用默认的 get accessor 和 set accessor,但接口的 private 一般实例属性及 virtual 的实例属性不可使用默认的 get accessor 和 set accessor。
  • 一个类只能继承单一的父类(包括抽象类),但可以实现多个接口。
  • 虽然在很多时候将抽象类和接口互换并不影响程序的行为,然而习惯上,抽象类及其子类描述一个实体,例如System.IO.Stream, Microsoft.AspNetCore.Mvc.Controller;而接口要求其实现类具有某个行为或性质,例如:System.Collections.IEnumerable, System.IComparable
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值