diff --git a/InterfaceStudy.App/InterfaceStudy.App.csproj b/InterfaceStudy.App/InterfaceStudy.App.csproj
new file mode 100644
index 0000000..3e17cb8
--- /dev/null
+++ b/InterfaceStudy.App/InterfaceStudy.App.csproj
@@ -0,0 +1,12 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
+
+
+
+
diff --git a/InterfaceStudy.App/Program.cs b/InterfaceStudy.App/Program.cs
new file mode 100644
index 0000000..fe62f3b
--- /dev/null
+++ b/InterfaceStudy.App/Program.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace InterfaceStudy.App
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("接口的各种操作!");
+ }
+
+ ///
+ /// 隐式实现
+ ///
+ public static void Test()
+ {
+
+ }
+
+ ///
+ /// 显式实现
+ ///
+ public static void Test2()
+ {
+
+ }
+ }
+}
diff --git a/InterfaceStudy.Core/ChildA.cs b/InterfaceStudy.Core/ChildA.cs
new file mode 100644
index 0000000..f8f8ec9
--- /dev/null
+++ b/InterfaceStudy.Core/ChildA.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace InterfaceStudy.Core
+{
+ public class ChildA : ExplicitBase, IBase
+ {
+ int Number = -1;
+
+ public override int GetNumber()
+ {
+ return --Number;
+ }
+ }
+}
diff --git a/InterfaceStudy.Core/ChildB.cs b/InterfaceStudy.Core/ChildB.cs
new file mode 100644
index 0000000..efb3320
--- /dev/null
+++ b/InterfaceStudy.Core/ChildB.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace InterfaceStudy.Core
+{
+ public class ChildB : ExplicitBase
+ {
+ //可使用new关键字,表明有意隐藏继承成员 ExplicitBase.Number
+ int Number = -1;
+
+ public override int GetNumber()
+ {
+ return --Number;
+ }
+ }
+}
diff --git a/InterfaceStudy.Core/ExplicitBase.cs b/InterfaceStudy.Core/ExplicitBase.cs
new file mode 100644
index 0000000..011557a
--- /dev/null
+++ b/InterfaceStudy.Core/ExplicitBase.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace InterfaceStudy.Core
+{
+ ///
+ /// 基接口显式实现类
+ ///
+ public class ExplicitBase : IBase
+ {
+ public int Number = 1;
+
+ public ExplicitBase()
+ {
+ ++Number;
+ }
+
+ int IBase.GetNumber()
+ {
+ Console.WriteLine("显式实现接口方法");
+ return Number;
+ }
+
+ public virtual int GetNumber()
+ {
+ Console.WriteLine($"基类与接口同名的虚方法!");
+ return Number;
+ }
+ }
+}
diff --git a/InterfaceStudy.Core/IBase.cs b/InterfaceStudy.Core/IBase.cs
new file mode 100644
index 0000000..6a332f4
--- /dev/null
+++ b/InterfaceStudy.Core/IBase.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace InterfaceStudy.Core
+{
+ ///
+ /// 基接口
+ /// 1 接口中的对象都是公开权限的,否则接口无意义:不能使用范围修饰符(public private internal protected)
+ /// 2 接口对象可以是属性 方法 索引 事件 委托等,接口只包含定义不能包含实现,并且不能直接实例化接口。
+ /// 3 接口对象不能是字段(字段本意为私有,与接口意义相背),
+ /// 4 不能有构造或析构函数(对象的创建与销毁,应该在实现类所关心的,接口只关心需要实现的功能[属性 方法 索引 事件 委托等]即可)
+ /// 5 不能有 static 修饰符,即对象不能是静态对象(静态的,本身就是实现;而接口是定义,是契约,只有实现了才有意义)
+ ///
+ public interface IBase
+ {
+ int GetNumber();
+ }
+}
diff --git a/InterfaceStudy.Core/ImplicitBase.cs b/InterfaceStudy.Core/ImplicitBase.cs
new file mode 100644
index 0000000..889efe6
--- /dev/null
+++ b/InterfaceStudy.Core/ImplicitBase.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace InterfaceStudy.Core
+{
+ ///
+ /// 基接口隐式实现类
+ ///
+ public class ImplicitBase : IBase
+ {
+ public int Number = 0;
+
+ ///
+ /// 1 必须是public
+ /// 2 可以用自己修饰符:virtual
+ ///
+ public int GetNumber()
+ {
+ return Number;
+ }
+ }
+}
diff --git a/InterfaceStudy.Core/InterfaceStudy.Core.csproj b/InterfaceStudy.Core/InterfaceStudy.Core.csproj
new file mode 100644
index 0000000..9f5c4f4
--- /dev/null
+++ b/InterfaceStudy.Core/InterfaceStudy.Core.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netstandard2.0
+
+
+
diff --git a/InterfaceStudy.Core/接口学习.md b/InterfaceStudy.Core/接口学习.md
new file mode 100644
index 0000000..0ee3244
--- /dev/null
+++ b/InterfaceStudy.Core/接口学习.md
@@ -0,0 +1,150 @@
+# 接口学习
+
+## 接口定义
+
+> 接口是一种契约和规范;是指定一组对象的定义而非实现的引用类型;是C#实现多继承的机制;也是多态的一种常用实现方式。
+
+## 接口特点
+
+1. 接口可以包含属性、方法、索引器、委托与事件等对象,但不能包含字段,也不能包含构造或析构函数(对象的创建与销毁,应该在实现类所关心的,接口只关心需要实现的功能约定)
+1. 接口中的对象都是公开权限的,否则接口无意义:不能使用范围修饰符(public private internal protected)
+1. 不能有 static abstract virtual override sealed 等违反接口意义的修饰符
+1. 接口只包含对象的定义,不能包含对象的实现,也不能直接实例化接口
+1. 接口的实现类必须实现接口中的所有成员,除非实现类本身是抽象类(通过具体的可执行代码实现接口抽象成员的操作);接口实现子类中,可用new关键字隐藏父接口中的方法。
+1. 接口可以多继承,可用来解决C#类的单继承问题
+1. 接口名称一般都以“I”作为首字母,以与实现类区分
+
+## 接口的隐式实现与显式实现
+
++ 接口
+
+``` csharp
+ ///
+ /// 接口
+ ///
+ public interface IBase
+ {
+ void Print();
+ }
+```
+
++ 隐式实现
+``` csharp
+ ///
+ /// 隐式实现接口
+ ///
+ public class Base : IBase
+ {
+ //必须有访问修饰符
+ //对象(方法)名,即是接口对象(方法)名
+ public void Print()
+ {
+ Console.WriteLine($"隐式实现接口方法");
+ }
+ }
+```
+
++ 显式实现
+``` csharp
+ ///
+ /// 显式实现接口
+ ///
+ public class Base : IBase
+ {
+ //不允许有访问修饰符
+ //对象(方法)名为”接口名.对象(方法)名"
+ void IBase.Print()
+ {
+ Console.WriteLine("显式实现接口方法");
+ }
+ }
+```
+
++ 语法区别
+ > 隐式实现必须加 *访问修饰符* 显式实现不能用任何*访问修饰符* ;隐式实现对象名是接口对象名,显式实现,对象名为*接口名.对象名*
++ 调用区别
+ > 隐式实现,可以由实现类或接口类调用;显式实现只能由接口类调用。
+
+ ``` csharp
+ //隐式实现调用
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ //接口类可以调用
+ IBase base = new Base();
+ base.Print();
+
+ //实现类可以调用
+ Base base2 = new Base();
+ base2.Print();
+ }
+ }
+
+ //显式实现调用
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ //接口类可以调用
+ IBase base = new Base();
+ base.Print();
+
+ //实现类不能调用
+ Base base2 = new Base();
+ //语法错误,不可调用
+ base2.Print();
+ }
+ }
+ ```
+
+小结:
+1. 通常情况下,使用隐式方式实现接口;
+2. 需要区分不同接口或者有同名对象时,使用显式实现;
+3. 业务需要时,使用显式实现
+
+## 接口继承
+
+## 子类重复实现父类接口
+```csharp
+///
+/// 接口
+///
+public interface IBase
+{
+ string GetA();
+ string GetB();
+}
+
+///
+/// 接口实现基类
+///
+public class Base : IBase
+{
+ public string GetA()
+ {
+ return "基类 GetA方法";
+ }
+
+ public string GetB()
+ {
+ return "基类 GetB方法";
+ }
+}
+
+///
+/// 接口实现子类
+///
+public class ChildA:Base,IBase
+{
+ public string GetB()
+ {
+ return "实现子类 GetB方法";
+ }
+}
+
+
+
+```
+
+## 运行时多态与编译时多态
\ No newline at end of file
diff --git a/InterfaceStudy.Test/BaseTest.cs b/InterfaceStudy.Test/BaseTest.cs
new file mode 100644
index 0000000..23995fd
--- /dev/null
+++ b/InterfaceStudy.Test/BaseTest.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Xunit;
+
+namespace InterfaceStudy.Test
+{
+ public class BaseTest
+ {
+ [Fact]
+ public void Test()
+ {
+
+ }
+ }
+}
diff --git a/InterfaceStudy.Test/ChildATest.cs b/InterfaceStudy.Test/ChildATest.cs
new file mode 100644
index 0000000..2487239
--- /dev/null
+++ b/InterfaceStudy.Test/ChildATest.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using InterfaceStudy.Core;
+
+using Xunit;
+
+namespace InterfaceStudy.Test
+{
+ public class ChildATest
+ {
+ [Fact]
+ public void Test()
+ {
+ IBase a = new ChildA();
+
+ var number = a.GetNumber();
+
+ Assert.Equal(-2,number);
+ }
+ }
+}
diff --git a/InterfaceStudy.Test/ChildBTest.cs b/InterfaceStudy.Test/ChildBTest.cs
new file mode 100644
index 0000000..b06467d
--- /dev/null
+++ b/InterfaceStudy.Test/ChildBTest.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using InterfaceStudy.Core;
+
+using Xunit;
+
+namespace InterfaceStudy.Test
+{
+ public class ChildBTest
+ {
+ [Fact]
+ public void Test()
+ {
+ IBase myBase = new ChildB();
+
+ var number = myBase.GetNumber();
+
+ Assert.Equal(2,number);
+ }
+ }
+}
diff --git a/InterfaceStudy.Test/DemoTest.cs b/InterfaceStudy.Test/DemoTest.cs
new file mode 100644
index 0000000..95db59e
--- /dev/null
+++ b/InterfaceStudy.Test/DemoTest.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Xunit;
+
+namespace InterfaceStudy.Test
+{
+ public class DemoTest
+ {
+ [Fact]
+ public void Test()
+ {
+ IDemo demo = new DemoA();
+ var result = demo.GetNumber();
+
+ Assert.Equal(2,result);
+ }
+
+ [Fact]
+ public void Test2()
+ {
+ IDemo demo = new DemoB();
+ var result = demo.GetNumber();
+
+ Assert.Equal(1,result);
+
+ var demoB = new DemoB();
+ var resultB = demoB.GetNumber();
+
+ Assert.Equal(3, resultB);
+ }
+ }
+
+ public interface IDemo
+ {
+ int GetNumber();
+ }
+
+ public class Demo : IDemo
+ {
+ int IDemo.GetNumber()
+ {
+ return 1;
+ }
+ }
+
+ public class DemoA : Demo, IDemo
+ {
+ public int GetNumber()
+ {
+ return 3;
+ }
+ }
+
+ public class DemoB : Demo
+ {
+ public int GetNumber()
+ {
+ return 3;
+ }
+ }
+}
diff --git a/InterfaceStudy.Test/InterfaceStudy.Test.csproj b/InterfaceStudy.Test/InterfaceStudy.Test.csproj
new file mode 100644
index 0000000..9b672cf
--- /dev/null
+++ b/InterfaceStudy.Test/InterfaceStudy.Test.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net5.0
+
+ false
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
diff --git a/InterfaceStudy.Test/UseXUnit.cs b/InterfaceStudy.Test/UseXUnit.cs
new file mode 100644
index 0000000..5f100a1
--- /dev/null
+++ b/InterfaceStudy.Test/UseXUnit.cs
@@ -0,0 +1,15 @@
+using System;
+
+using Xunit;
+
+namespace InterfaceStudy.Test
+{
+ public class UseXUnit
+ {
+ [Fact]
+ public void Test1()
+ {
+ Assert.True(true,"ʹXUnit");
+ }
+ }
+}
diff --git a/InterfaceStudy.sln b/InterfaceStudy.sln
new file mode 100644
index 0000000..edc2537
--- /dev/null
+++ b/InterfaceStudy.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31410.357
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterfaceStudy.Core", "InterfaceStudy.Core\InterfaceStudy.Core.csproj", "{2F771F8A-B472-485D-816A-BB5B5C828DE2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterfaceStudy.App", "InterfaceStudy.App\InterfaceStudy.App.csproj", "{5578DC19-F9A7-4FE0-AB74-6A583A30E99B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterfaceStudy.Test", "InterfaceStudy.Test\InterfaceStudy.Test.csproj", "{B7B58056-A189-4628-BE74-A16165B04BF7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2F771F8A-B472-485D-816A-BB5B5C828DE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2F771F8A-B472-485D-816A-BB5B5C828DE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2F771F8A-B472-485D-816A-BB5B5C828DE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2F771F8A-B472-485D-816A-BB5B5C828DE2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5578DC19-F9A7-4FE0-AB74-6A583A30E99B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5578DC19-F9A7-4FE0-AB74-6A583A30E99B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5578DC19-F9A7-4FE0-AB74-6A583A30E99B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5578DC19-F9A7-4FE0-AB74-6A583A30E99B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B7B58056-A189-4628-BE74-A16165B04BF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B7B58056-A189-4628-BE74-A16165B04BF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B7B58056-A189-4628-BE74-A16165B04BF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B7B58056-A189-4628-BE74-A16165B04BF7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A49848D2-019D-499A-8950-BF411F1B7512}
+ EndGlobalSection
+EndGlobal