为什么我们需要为接口创建实例而不是为了实现? [英] Why we need to create instance for interface not for implementation?

查看:63
本文介绍了为什么我们需要为接口创建实例而不是为了实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怀疑在界面或具体类上创建实例..

I have doubt in creating an instance over interface or concrete class..

推荐答案

你不明白这里最基本的编程思想之一:编译时类型 vs 运行时类型

了解何时进行任何类型的继承非常重要:使用接口或基类。当你有一个类的变量的成员时,你声明它的编译时类,但运行时类型可以是不同的,因为这个引用对象是赋值兼容与派生类。



例如:
You don't understand one of the most basic programming ideas here: compile-time types vs runtime types.
It's important to understand when you do any kind of inheritance: with interfaces or base classes. When you have a member of a variable of some class, you declare its compile-time class, but runtime type can be different, because this reference object is assignment-compatible with a derived class.

For example:
class Base { /* .. */ }
class Derived : Base { /* ... */ }

// ...

Base @object = // compile-time type is Base
new 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 thing

interface 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 this

ISomeContract first = new Implementation();
ISomeOtherContract second = new Implementation();

first.A(); // yes, you can, but not first.B(), even though B is also implemented
second.B(); // // yes, you can, but not first.A(), even though A is also implemented



你能看出这一点吗?您有两个具有相同运行时类型的对象,但编译时类型是接口。这就像从不同界面的角度看同一个对象,代表同一个对象的不同方面



当然,您可以将此对象转换为另一种接口类型,但这会破坏目的并且会违反OOP。同样,您无法访问 SomethingElse ,这需要引用类型 Implementation 。目标是无法访问(我们是否遇到访问问题?:-)),但隔离。有趣的是,这样,同一个对象可以根据不同的类型参与不同的多态集合。



另请参阅本文中引用的过去答案:对接口的疑虑 [ ^ ]。



-SA


Can 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[^].

—SA


编程到接口不具体这是一个很好的概念。

在MSDN中关于接口说

接口包含一组类或结构可以实现的一组相关功能的定义。

没关系..但是人们对于为什么接口不是完全可以理解的,我们何时何地使用接口为什么推荐编程到接口而不是具体......我们脑子里有很多问题。



为什么我们使用接口?

1.可扩展性

2.可维护性

3.Testabilty



我不是在说这个关于详细信息。但我想分享一些关于扩展性的东西。这是关于接口的最好的事情之一。



假设在我的应用程序中我使用Sqlserver进行存储和检索数据。所以我要创建一个类来保存客户信息。

业务逻辑



Programming to an Interfaces Not Concrete it's a good concept.
In MSDN about interface says
An interface contains definitions for a group of related functionalities that a class or a struct can implement.
It's Ok..But people's are not fully understandable about Why interfaces , Where and when we use interfaces why recommending Programming to an interface not concrete..a lot of questions in our mind.

Why we use Interfaces?
1.Extensibility
2.Maintainability
3.Testabilty

I am not telling this about detail..But l would like to share something about Extensibility.It's one of the best thing about interfaces.

Suppose In my application i am using Sqlserver for storing and retrieving the data.So i am going to create one class for saving Customer information.
Business Logic

public class CustomerRepository{

public void Save(){//logic for saving data}
public void Update{}
//some other operations here
} 





应用层

在我的应用层,如果我想保存客户信息,我们应该创建一个类的实例并调用下面的保存方法



Application Layer
In 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 below

CustomerRepository 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 interfaces

public 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 Layer

public 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 trust
So i am going to create one more class CustomerFileRepository and implement the same interfaces we have created before

public 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 Code

public 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 below

public 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 [ ^ ]

< a href =http://www.codeproject.com/Articles/526874/Repositorypluspattern-cplusdoneplusright>存储库模式,完成正确 [ ^ ]



希望此信息可以帮助您



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 concept
If 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


请记住,接口永远不会有来自接口的'实例:类或结构继承。请注意,接口可以从另一个接口继承,并且可以通过添加其他对象的签名来扩展



这些类或结构,继承自接口必须实现接口中定义的每个方法,属性,事件或索引器,以便实现与接口指定的签名匹配。



类或实例的实例是由程序执行创建的,无论是在应用程序加载时......还是在运行时,通过编程。



我不确定你的意思是具体类:也许你正在考虑一个抽象类,它就像一个接口,因为它可能包含签名,并且永远无法实例化但是,它可以提供方法的默认实现。



注意Class或Struct只能从一个抽象类继承。



我建议你阅读:[ ^ ],[ ^ ],[ ^ ]。
Do keep in mind that an Interface never has an 'instance: Classes, or Structs inherit from Interface(s). Note that an Interface can inherit from another Interface, and may extend it by adding additional objects' signatures.

Those Classes, or Structs, that inherit from Interface(s) must implement each Method, Property, Event, or Indexer, defined in the Interface so the implementation matches the signatures the Interface specifies.

Instances of Classes, or Structs, are created by program execution, either when the application loads ... or, at run-time, by programming.

I'm not sure what you mean by "concrete class:" perhaps you are thinking of an Abstract Class, which is like an Interface in that it may contain signatures, and can never be instantiated, but, it can provide a default implementation of methods.

Note that a Class or Struct, can only inherit from one Abstract Class.

I suggest you read: [^], [^], [^].


这篇关于为什么我们需要为接口创建实例而不是为了实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆