ArrayList<Class> name = new ArrayList<Class>(#)
昨天有人告诉我,这样的做法是不好的做法,我应该“针对界面”进行编程,如下所示:
List<Class> name = new ArrayList<Class>(#)
他是什么意思?
ArrayList
实现List
。List
因此,出于多种原因,最好使用。例如,如果您希望将来更改列表的类型(例如,您决定使用 a LinkedList
、Stack
或Vector
),您只需要更改赋值的右侧,其余代码就可以正常工作,不变。
无需透露您正在使用的 List 的确切实现。
唯一可用的方法是接口中的方法。从技术上讲,这并不重要,但这是一个很好的习惯。代码更干净,更易于维护。
该代码片段中的“接口”是List
一个比ArrayList
.
List 将由许多其他类实现,如 ArrayList、LinkedList 等......
通过使用接口来声明name
,那么用户name
不必知道列表name
实际上是哪种类型,并且如果您决定将来使用不同类型的列表,您可以不必更改代码中的很多地方。
理想情况下,您希望使用集合的接口而不是集合变量和返回值的实现。在您的示例中,这不是什么大问题。在编写方法时,它确实变得更有用:
public List<String> doSomething() {
}
通过 usingList<String>
和 not ArrayList<String>
,此方法可以选择使用不同的列表(例如,它可能会更改为 LinkedList ),但 API 的协定不会改变,因此所有调用代码仍然有效,即使该方法现在返回不同类型的列表。
在接口中定义了哪些方法是可用的,所以当一个类被写来实现一个接口时,它必须有接口中定义的方法。(它也可能有其他方法)
假设您编写了一个其他人将使用的类,并且它具有这样的方法:
public void doSomething(List<Thing> aListOfThings) {
//some code to manipulate the list
}
当其他人编写代码来使用您的类时,您并不关心他们使用什么类型的 List 来调用您的方法。所有这些都是有效的:
yourClass.doSomething(new ArrayList<Thing>());
yourClass.doSomething(new AttributeList<Thing>());
yourClass.doSomething(new Vector<Thing>());
yourClass.doSomething(new SomeOtherTypeOfList<Thing>());
他们可以自由选择适合其目的的列表类型(实现)。
List<Class> name = new ArrayList<Class>(#)
SuperType ref = SubTypeObj
这是创建 ArrayList 的多态方式。List 是 ArrayList 的超类型。像这样创建数组列表的好处是:
您可以稍后参考相同的列表来创建 LinkedList。
名称 = 新的链表(#)
他的意思是你应该只使用你需要的变量类型。例如,除非您使用仅定义在的方法,否则ArrayList
您应该使用List
. 同样,如果您不需要任何来自List
然后使用Collection
等。
有两个原因:
1)它使将来更容易将实现更改为另一种类型。假设您正在使用一些使用 a 的 ORM,LazilyLoadedList
那么如果您的所有代码都反对,List
那么您可以轻松地将其插入。如果反对,ArrayList
那么您需要更改大量方法签名并确保您不依赖于ArrayList
特定方法。这是什么的一部分
2)使用 JMock 或 Mockito 等工具更容易模拟接口。
这应该可以帮助您了解接口是什么以及它在软件开发中的用途。
假设您需要将包裹邮寄给某人。有许多承运商选择:USPS、UPS、FedEx 等。
现在想象一下,如果有一个中央邮箱,您可以将包裹放入其中,并且所有承运人都可以从该邮箱投递。所以,你不在乎它是如何被 USPS、UPS 或 FedEx 接收的。您需要做的就是将包裹带到邮箱并投递。它实际上如何交付与您无关。
在此示例中,您可以将接口定义为:
public interface IMailService
{
void SendMail(obj myMailObj);
}
然后您可以将 MailService 的具体实现定义为:
public class USPSMailService : IMailService
{
public void SendMail(obj myMailObj)
{
//This code executes SendMail using USPS' implementation
}
}
public class UPSMailService : IMailService
{
public void SendMail(obj myMailObj)
{
//This code executes SendMail using UPS' implementation
}
}
public class FedExMailService : IMailService
{
public void SendMail(obj myMailObj)
{
//This code executes SendMail using FedEx's implementation
}
}
然后,当您想在代码中发送邮件时,您可以这样编写:
IMailService mailService = new FedExMailService();
mailService.SendMail(myMailObj);
如果您以后需要使用 UPS 的邮件服务,那么您需要做的就是使用 UPS 类型进行实例化。其余代码,包括对 SendMail() 的所有调用保持不变:
mailService = new UPSMailService();
现在,如果 UPS 提供其他运营商不提供的某些服务,那么您需要将变量定义为具体类型。
例如,如果 UPS 类别是这样定义的:
public class UPSMailService : IMailService
{
public void SendMail(obj myMailObj)
{
//This code executes SendMail using UPS' implementation
}
//This is a method that only UPS offers
public void SendMailOnSunday(obj myMailObj)
{
//This code executes UPS' proprietary method
}
}
那么您的代码将需要像这样使用具体类:
UPSMailService mailService = new UPSMailService();
mailService.SendMailOnSunday(myMailObj);