简体   繁体   English

界面与具体类

[英]Interface versus concrete class

Below I have a Person interface, an implementing class and a driver class which initialises the Person with a name and just outputs it again. 下面我有一个Person接口,一个实现类和一个驱动程序类,它使用一个名称初始化Person并再次输出它。 What is the advantage of using 使用的优点是什么

Person person = new PersonImpl();

instead of 代替

PersonImpl person = new PersonImpl();

The interface is supposed to be hiding the implementation? 该接口应该隐藏实现? Is this the correct way of using interfaces? 这是使用接口的正确方法吗?

public class Driver {

    public static void main(String [] args)
    {
        Person person = new PersonImpl();
        person.setName("test name");
        System.out.println("Name is "+person.getName());
    }

}


public interface Person {

    public void setName(String name);

    public String getName();

}


public class PersonImpl implements Person{

    private String name;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

This is the way to use interfaces. 这是使用接口的方式。

The reason is so you could write another implementation later without changing code that uses Person . 原因是您可以在以后编写另一个实现,而无需更改使用Person代码。

So for now you can use PersonImpl but later you might need a OtherTypeOfPersonImpl . 所以现在你可以使用PersonImpl但是稍后你可能需要一个OtherTypeOfPersonImpl

You could create the new class implementing the same interface, and you could use the new class with any other code that expects a Person . 您可以创建实现相同接口的新类,并且可以将新类与任何其他需要Person代码一起使用。

A good example is the List interface. 一个很好的例子是List接口。

There are multiple implementations of List such as ArrayList , LinkedList , etc. Each of these has advantages and disadvantages. List有多种实现,例如ArrayListLinkedList等。它们中的每一种都有优点和缺点。 By writing code that uses List , you can let each developer decide what type of List works best for them and be able to handle any of them without any changes. 通过编写使用List代码,您可以让每个开发人员确定哪种类型的List最适合他们,并且能够在不做任何更改的情况下处理任何类型的List

what you did is correct. 你所做的是正确的。 the advantage in using Person person = new PersonImpl() is that a loose coupling is maintained between the interface and the concrete implementation. 使用Person person = new PersonImpl()的优点是在接口和具体实现之间保持松耦合。 PersonImpl person = new PersonImpl() is tightly coupled. PersonImpl person = new PersonImpl()紧密耦合。 and Person person = new Person() won't even compile. Person person = new Person()甚至不会编译。

imagine you have a huge application, and a lot of code depends on the PersonImpl object. 想象一下你有一个庞大的应用程序,很多代码依赖于PersonImpl对象。 now suppose i want to change PersonImpl and make a new class, PersonImpl2. 现在假设我要更改PersonImpl并创建一个新类PersonImpl2。 now i have to manually scan through the whole project and make changes everywhere. 现在我必须手动扫描整个项目并在各处进行更改。 this might even break the code. 这甚至可能会破坏代码。 this is called tight coupling, and is a bad thing. 这被称为紧耦合,是一件坏事。 instead, if the rest of the code depended on a Person object, then even if i make a new PersonImpl2 class, things will work fine because PersonImpl2 implements Person. 相反,如果代码的其余部分依赖于Person对象,那么即使我创建一个新的PersonImpl2类,事情也会正常工作,因为PersonImpl2实现了Person。

One advantage I can think of is that you might have 2 very different types of people, but you want to wait until runtime (based on user input, config file, etc.) to decide which one to use. 我能想到的一个优点是你可能有两种非常不同类型的人,但你想等到运行时(基于用户输入,配置文件等)来决定使用哪一种。 You can do something like this: 你可以这样做:

Person person = null;
if ...
   person = new PersonImpl();
else 
   person = new PersonImpl2();

It depends on how you want to use Person. 这取决于你想如何使用Person。

As it stands, you don't gain any real benefit from having it an interface. 就目前而言,拥有界面并不会带来任何实际好处。

However, suppose there were aliens who could also be considered a "Person" because of their behaviors (say "talks(), walks(), thinks(), feels()) that are defined in Person. Now you might want to separate "Person" from "Human" and "Alien" so that individuals from two very different hierarchies -- say "Humans" in the "mammal" hierarchy and "Aliens" in the "arachnid" hierarchy -- could both implement the Person interface. 但是,假设有外星人也可以被认为是“人”因为他们的行为(比如说“讲话(),行走(),思考(),感觉()”,这些都是在人物中定义的。现在你可能想分开来自“人类”和“外星人”的“人”使得来自两个非常不同的等级的个体 - 在“哺乳动物”层次结构中称为“人类”,在“节肢动物”层次结构中称为“外星人” - 可以实现人员界面。

Using the interface instead of the concrete class would let you change the implementation later. 使用接口而不是具体类可以让您稍后更改实现。

This about JDBC, all of it is based on interfaces, so the driver can implement it later. 关于JDBC,所有这些都基于接口,因此驱动程序可以在以后实现它。

For instance when you use a ResulSet you don't really care how or what underlaying implementation is ( with a Oracle Driver would be something like OracleResultSet, with a MySQL driver could be something like MySQLResultSet ) but you know what methods are available for you to use. 例如,当您使用ResulSet时,您并不关心底层实现的方式或内容(Oracle驱动程序将类似于OracleResultSet,MySQL驱动程序可能类似于MySQLResultSet),但您知道有哪些方法可供您使用使用。

Same goes with List or Map, instead of ArrayList or HashMap 与List或Map相同,而不是ArrayList或HashMap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM