Java接口作为引用类型?
我应该在哪里使用接口作为变量类型?我看到很多人说这样做是最好的做法,但每个例子都涉及到收藏:Java接口作为引用类型?,java,variables,types,interface,reference,Java,Variables,Types,Interface,Reference,我应该在哪里使用接口作为变量类型?我看到很多人说这样做是最好的做法,但每个例子都涉及到收藏: List<String> list = new ArrayList<>() List List=new ArrayList() 这种做法主要适用于收藏吗? 例如,我从未见过有人在声明I/o流时使用接口。其思想是,如果实际实现不重要,则要隐藏它。这通常会使代码更简单,并避免意外地使用特定于实现的特性 因此,只能将ArrayList与new一起使用。在其他地方使用列表。(除非你有
List<String> list = new ArrayList<>()
List List=new ArrayList()
这种做法主要适用于收藏吗?
例如,我从未见过有人在声明I/o流时使用接口。其思想是,如果实际实现不重要,则要隐藏它。这通常会使代码更简单,并避免意外地使用特定于实现的特性 因此,只能将
ArrayList
与new
一起使用。在其他地方使用列表
。(除非你有充分理由这样做)
注意:对于Java 10,可以对局部变量使用var
语法:
var list = new ArrayList<String>();
var list=new ArrayList();
这个想法是,如果实际实现不重要,您希望隐藏它。这通常会使代码更简单,并避免意外地使用特定于实现的特性
因此,只能将ArrayList
与new
一起使用。在其他地方使用列表
。(除非你有充分理由这样做)
注意:对于Java 10,可以对局部变量使用var
语法:
var list = new ArrayList<String>();
var list=new ArrayList();
使用接口比使用具体类更好,因为如果您想切换实现,则更容易。但这只适用于你从中获益的情况;在5行的方法中使用List而不是ArrayList在代码中不会有太大变化。
当您将它们作为方法或构造函数的引用接收时,优势更大,因为您使用接口/契约,并且代码的“用户”(可能是您)可以轻松地通过另一个实现来改进程序或作为测试中的模拟
对于I/O,使用
InputStream
和OutpuStream
非常常见,具体类型由用户自行决定。因此,您可以使用InputStream
从网络或本地文件进行读取。使用接口比使用具体类更好,因为如果您想要切换实现,则更容易。但这只适用于你从中获益的情况;在5行的方法中使用List而不是ArrayList在代码中不会有太大变化。
当您将它们作为方法或构造函数的引用接收时,优势更大,因为您使用接口/契约,并且代码的“用户”(可能是您)可以轻松地通过另一个实现来改进程序或作为测试中的模拟
对于I/O,使用
InputStream
和OutpuStream
非常常见,具体类型由用户自行决定。因此,您可以使用InputStream
从网络或本地文件中读取。引用接口是最佳做法,因为通过这种方式,您始终可以更改实际实现,而无需修改该接口的调用者。假设您有一个类似Spring的CDI环境。您的ServiceInterface
可以有多个实现,但控制器永远看不到实际的实现
控制器:
@Controller
public class MyController {
@Autowired
private ServiceInterface service;
/*stuff*/
}
服务接口:
public interface ServiceInterface{ /*stuff*/ }
实施“A”:
实施“B”:
Spring有自己的选择实现(称为概要文件)的机制,但也有类似工厂的替代方案。只要接口不变,您就可以在两个服务实现之间切换:控制器类不会检测到任何变化 引用接口是一种最佳实践,因为通过这种方式,您始终可以在不修改该接口调用方的情况下更改实际实现。假设您有一个类似Spring的CDI环境。您的
ServiceInterface
可以有多个实现,但控制器永远看不到实际的实现
控制器:
@Controller
public class MyController {
@Autowired
private ServiceInterface service;
/*stuff*/
}
服务接口:
public interface ServiceInterface{ /*stuff*/ }
实施“A”:
实施“B”:
Spring有自己的选择实现(称为概要文件)的机制,但也有类似工厂的替代方案。只要接口不变,您就可以在两个服务实现之间切换:控制器类不会检测到任何变化 这是一种远见卓识。是的,有一条规则 始终为接口编写代码 但是为什么呢
定义类型使用
newarraylist()
,声明类型使用List
。这是个好习惯。现在让我们想想,通常情况下,ArrayList
的当前性能非常适合您的数据和程序。如果存在新的容器类型,例如称为niceporformedlist
,它也实现了List
接口,并使您的程序性能在5年后大大提高,您是否会重构所有声明性类型,而不是仅仅更改定义类型?这是一种长远考虑。是的,有一条规则
始终为接口编写代码
但是为什么呢
定义类型使用
newarraylist()
,声明类型使用List
。这是个好习惯。现在让我们想想,通常情况下,ArrayList
的当前性能非常适合您的数据和程序。如果存在新的容器类型,例如称为NicePerformedList
,它也实现了List
接口,使您的程序性能在5年后大大提高,该怎么办,您是否会重构所有声明性类型,而不仅仅是更改定义类型?当不同类之间有不同的方法实现时,最好使用带有此方法签名的接口并在类中实现它们。因此,无论使用哪种实现,我们都可以使用接口作为变量,或者将其作为内部变量传递给其他方法
interface MathInterface{
int sum();
}
class A implements MathInterface
{
@Override
int sum()
{
//implementation
}
}
class B implements MathInterface
{
@Override
int sum()
{
//implementation
}
}
class Main
{
MathInterface mathInterface=new B();
doSomeThing(mathInterface);
}
当有不同意见时