Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/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#_Java_Oop_Inheritance_Interface - Fatal编程技术网

C# 为什么在赋值声明中,在左边声明一个接口,在右边声明一个实现类?

C# 为什么在赋值声明中,在左边声明一个接口,在右边声明一个实现类?,c#,java,oop,inheritance,interface,C#,Java,Oop,Inheritance,Interface,我在Java和C代码中经常注意到这种模式,因此出于某种原因,我认为这是一种“最佳实践”,但我不确定为什么。例如,在Java中,我可能会看到 List<String> list = new ArrayList<String>(); List List=new ArrayList(); 这只在一个地方声明(显然),并且只适用于一个代码块,这有什么意义?为什么不说 ArrayList<String> list = new ArrayList<String&

我在Java和C代码中经常注意到这种模式,因此出于某种原因,我认为这是一种“最佳实践”,但我不确定为什么。例如,在Java中,我可能会看到

List<String> list = new ArrayList<String>();
List List=new ArrayList();
这只在一个地方声明(显然),并且只适用于一个代码块,这有什么意义?为什么不说

ArrayList<String> list = new ArrayList<String>();
ArrayList list=new ArrayList();

是的,这是最佳实践。 因为在以后的代码中,您可以使用
LinkedList
CustomListImpl
更改实现,而无需更改客户端代码

假设您使用具有以下方法的某个第三方库:

ArrayList<Document> getAllDocuments(){...}
如果库方法将与接口一起声明

List<Document> getAllDocuments(){...}

因此,使用
接口
允许您在抽象层而不是实现层上创建程序。是的,这是最佳实践。 因为在以后的代码中,您可以使用
LinkedList
CustomListImpl
更改实现,而无需更改客户端代码

假设您使用具有以下方法的某个第三方库:

ArrayList<Document> getAllDocuments(){...}
如果库方法将与接口一起声明

List<Document> getAllDocuments(){...}
因此,使用
接口
允许您在抽象层而不是实现层

上创建程序,因为
列表
声明了一个能够响应
列表
接口可用的所有方法的对象。
ArrayList
可以有更多方法可用于该特定实现

宣布

ArrayList<String> list = new ArrayList<String>();
然后你可以直接把它改成

List<String> list = new LinkedList<String>();
List List=newlinkedlist();
保证不破坏代码中的任何其他内容,因为
list
仅用作
list
,因此您没有在其上使用任何额外功能

一般来说,对特定类型的假设越少越好。这是因为您只是通过一个接口与类型交互,所以您不关心确切的类型是什么或它有什么额外的功能,您只关心接口提供的方法。当然,这并不总是可能的,因为有时您需要使用特定的功能。

因为
列表
声明了一个能够响应
列表
接口可用的所有方法的对象。
ArrayList
可以有更多方法可用于该特定实现

宣布

ArrayList<String> list = new ArrayList<String>();
然后你可以直接把它改成

List<String> list = new LinkedList<String>();
List List=newlinkedlist();
保证不破坏代码中的任何其他内容,因为
list
仅用作
list
,因此您没有在其上使用任何额外功能


一般来说,对特定类型的假设越少越好。这是因为您只是通过一个接口与类型交互,所以您不关心确切的类型是什么或它有什么额外的功能,您只关心接口提供的方法。当然,这并不总是可能的,因为有时您需要使用特定的功能。

有很多重复项。流行的原因是,您可以在不中断代码的情况下更改类型(到实现该接口的另一个类型)。另一个(.NET only):
IEnumerable
无法修改集合,因为添加,移除或清除方法来自子界面
ICollection
。因此,如果您希望它是不可变的,请使用基本接口。存在大量重复项。流行的原因是,您可以在不中断代码的情况下更改类型(到实现该接口的另一个类型)。另一个类型(.NET only):
IEnumerable
无法修改集合,因为add,移除或清除方法来自子界面
ICollection
。所以如果你想让它保持不变,请使用基本接口。我意识到我的问题是重复的,但回答很好,谢谢。我意识到我的问题是重复的,但回答很好,谢谢。