本文介绍了为什么我们需要为接口创建实例而不是为了实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我怀疑在界面或具体类上创建实例..I have doubt in creating an instance over interface or concrete class..推荐答案class Base { /* .. */ }class Derived : Base { /* ... */ }// ...Base @object = // compile-time type is Basenew Derived(); // runtime type is Derived It了解整个OOP以了解为什么需要这样做。基类可以用作隐藏实现细节的契约和派生类中的不同实现,用于创建多态集。 现在,接口不是类,但您可以将接口视为一种特殊类型的类,它不能包含任何实现,任何静态成员或类型定义。接口允许多重继承,它们也可以通过 struct 实现,而不仅仅是类。当然,接口不能是任何真正存在的对象的运行时类型,只能是类或结构。 (可以实例化基类,为了防止它,需要声明它 abstract 和/或阻止访问继承树之外的代码的所有构造函数。) 所以,对于接口,我们有相同的东西It takes understanding of the whole OOP to understand why this is needed. Base class can be used as a contract hiding implementation detail and different implementation in derived classes, which is used to create polymorphous sets.Now, interface is not a class, but you can consider interface as a special kind of a class which cannot have any implementations, any static members or type definitions in it. The interfaces allows multiple inheritance, they also can be implemented by struct, not just classes. Naturally, interface cannot be a runtime type of any really existing object, only a class or a structure can be. (Base class can be instantiated, to prevent it, one needs to declare it abstract and/or prevent access to all its constructors for code outside the inheritance tree.)So, with interfaces, we have the same thinginterface ISomeContract { void A(); /* .. */ }interface ISomeOtherContract { void B(); /* .. */ }class Implementation : ISomeContract, ISomeOtherContract { void ISomeContract.A() { /* ... */ } void IOtherSomeContract.A() { /* ... */ } internal int SomethingElse; // cannot be accessed // through interface // (even with public :-) // ...}// ...// Now, consider thisISomeContract first = new Implementation();ISomeOtherContract second = new Implementation();first.A(); // yes, you can, but not first.B(), even though B is also implementedsecond.B(); // // yes, you can, but not first.A(), even though A is also implemented 你能看出这一点吗?您有两个具有相同运行时类型的对象,但编译时类型是接口。这就像从不同界面的角度看同一个对象,代表同一个对象的不同方面。 当然,您可以将此对象转换为另一种接口类型,但这会破坏目的并且会违反OOP。同样,您无法访问 SomethingElse ,这需要引用类型 Implementation 。目标是无法访问(我们是否遇到访问问题?:-)),但隔离。有趣的是,这样,同一个对象可以根据不同的类型参与不同的多态集合。 另请参阅本文中引用的过去答案:对接口的疑虑 [ ^ ]。 -SACan you see the point? You have two object of the same runtime type, but the compile-time types are interfaces. This is like looking at the same object from the point of view of different interfaces, representing different aspects of the same object.Of course, you can cast this object to another interface type, but this would defeat the purpose and would be some violation of OOP. Likewise, you cannot access SomethingElse, which requires reference of the type Implementation. The goal is no access (do we ever have problems with access? :-)), but isolation. Interestingly, this way, the same object can participate in different polymorphous sets based on different types.See also my past answers referenced in this one: Doubts on Interfaces[^].—SApublic class CustomerRepository{public void Save(){//logic for saving data}public void Update{}//some other operations here} 应用层 在我的应用层,如果我想保存客户信息,我们应该创建一个类的实例并调用下面的保存方法Application LayerIn my application layer if i want to save a Customer information we should create an instance of a class and call the save method like belowCustomerRepository objCustomer=new CustomerRepository();objCustomer.Save(); 好​​的..我们完成了所有功能。几天后我们的客户说我不想从数据库中提取数据我有一些文件系统或一些服务。嗯.. 如何处理这种情况? 我们必须修改我们的应用程序层以及业务逻辑。这里接口进入图片。 基于接口修改我们现有的应用程序Ok fine..We done all of the functionalities. After some days our client says i don't want to pull the data from Database i have some file system or some services.Hmmm..How to handle this situation?We have to modify our application layer as well as the business logic. Here Interfaces come in to the picture.Modifying our existing application based on interfacespublic interface ICustomerRepository{void Save();void Update();}public class CustomerRepository:ICustomerRepository{public void Save(){//logic for saving data}public void Update{}//some other operations here} 修改我们的应用层Modifying our Application Layerpublic class SomeApplicationLevelClass{private ICustomerRepository _customerRepository;public SomeApplicationLevelClass(){//manual dependency injection._customerRepository=new CustomerRepository();}public void SaveCustomer(){_customerRepository.Save();}} 现在我的数据访问权限从数据库更改为文件。 注意:保持现有的CustomerRepository类。它的工作功能。如果我们修改它将容易出错。在未来客户端也需要数据库访问权限。我们无法信任 所以我要再创建一个类CustomerFileRepository并实现我们之前创建的相同接口Now my data access change from DB to File.Note: keep the existing CustomerRepository class. It's working functionality. If we modify it will make error prone. In future client need db access also.We can't trustSo i am going to create one more class CustomerFileRepository and implement the same interfaces we have created beforepublic class CustomerFileRepostory:ICustomerRepository{public void Save(){//logic for saving data to file}public void Update{}} 修改应用层。 以前我们应该在所有地方直接更改所有具体实现。在这里我手动在构造函数中注入依赖项。所以我们只修改构造函数。你也可以通过配置使用依赖注入API来注入依赖项。对于微软技术,我们可以使用Ninject,Unity,StructureMap依赖容器。 修改后的代码Modifying application Layer.Previously we should change all concrete implementation directly in all places. here i am manually injecting dependencies in our constructor.So we only modify the constructor.You can also inject dependencies via configuration by using Dependency Injection API's.For microsoft technologies we can use Ninject,Unity,StructureMap dependency containers.Modified Codepublic class SomeApplicationLevelClass{private ICustomerRepository _customerRepository;public SomeApplicationLevelClass(){//manual dependency injection.//changes in constructor only_customerRepository=new CustomerFileRepository();}public void SaveCustomer(){_customerRepository.Save();}} 应用依赖注入设计模式后,您的代码将如下所示After applying the Dependency Injection Design Pattern your code will look like belowpublic class SomeApplicationLevelClass{private ICustomerRepository _customerRepository;public SomeApplicationLevelClass(ICustomerRepository customerRepository){//manual dependency injection.//changes in constructor only_customerRepository=customerRepository;}public void SaveCustomer(){_customerRepository.Save();}} 我们不需要在应用层提及我们的具体实现。关于具体类的一切都可以在依赖注入配置部分配置。如果你想再次更改为db.you只在配置或构造函数中修改。 现在我们的应用程序在一种可扩展的方式。我希望你对接口和编程接口的具体概念有一点了解 如果你对接口有更多了解,你应该深入了解以下内容。掌握这些东西需要一些时间,但你会逐渐得到更多。 http://stackoverflow.com/questions/130794/what-is-dependency-injection [ ^ ] 松散耦合的依赖注入 [ ^ ] 使用简单C#示例的SOLID架构原则 [ ^ ] http://www.oodesign.com/factory-pattern.html [ ^ ] 存储库模式,完成正确 [ ^ ] 希望此信息可以帮助您we no need to mention our concrete implementation in application layer. Everything about concrete class can configure in dependency injection configuration section.If you want to change again to db.you only modify in the configuration or constructor.Now our application in an Extensible way.I Hope you are got little bit idea about why interfaces and Programming to an interface not concrete conceptIf you know more about interfaces you should know the following things deeply. It will take some time to grasp those things but you will get more gradually.http://stackoverflow.com/questions/130794/what-is-dependency-injection[^]Dependency Injection for Loose Coupling[^]SOLID architecture principles using simple C# examples[^]http://www.oodesign.com/factory-pattern.html[^]Repository pattern, done right[^]Hope this information helps you 这篇关于为什么我们需要为接口创建实例而不是为了实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-22 12:58