简体   繁体   English

2个不同的Java类,使用相同的方法,但一个实现一个接口

[英]2 Different java classes,exact same methods but one implements an interface

Suppose, there are two java classes. 假设有两个java类。

BaseA

public class BaseA extends ModuleBase{
   public void doSomething{
    //does something
   }

}

BaseB

public class BaseB extends ModuleBase implements
    SomeInterface {
   public void doSomething{
    //does something
   }

}

SomeInterface

public interface SomeInterface {
  public void doSomething();
}

so as you can see the only difference between BaseA & BaseB is that BaseB implements an interface. 因此,您可以看到BaseABaseB之间的唯一区别是BaseB实现了一个接口。 As far my understanding an interface is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types. 据我所知,接口是类似于类的引用类型,它只能包含常量,方法签名,默认方法,静态方法和嵌套类型。 It cannot be instantiated. 无法实例化。

Questions: 问题:

  1. it seems BaseA & BaseA would be same as the methods & code in them is same. 看来BaseABaseA会与它们中的方法和代码相同。 correct? 正确?
  2. Interface seems like a contract that spells out how software APIs interact with each other & have no effect on class functions. 接口似乎是一种合约,阐明了软件API如何相互交互,并且对类功能没有影响。 only purpose of interface is to enforce that BaseB has mandatorily implement doSomething , where as with BaseA , its optional & won't generate compile errors. 接口的唯一目的是强制执行BaseB强制执行doSomething ,与BaseA ,其可选的不会产生编译错误。 if not, then why? 如果没有,那为什么呢?
  3. What difference implementing an interface make? 实现接口有什么不同? I know you have to implement all methods of that particular interface but if can also you do that without the keyword implements InterfaceName as seen in BaseB Vs BaseA where we implemented exact same doSomething() . 我知道您必须实现该特定接口的所有方法,但是如果可以,也可以不用关键字implements InterfaceName来做到这一点,如在BaseB VS BaseA中所看到的BaseA ,我们在其中实现了完全相同的doSomething() what difference having the keyword implements InterfaceName in class declaration make? 在类声明中使用关键字implements InterfaceName有什么区别?
  1. No. Classes in Java are the same when they have the same fully qualified name and when they were loaded from the same classloader. 否。Java中的类具有相同的完全限定名称并且从相同的类加载器加载时,它们是相同的。 Java makes no attempt to look into methods and it doesn't compare method signatures. Java不会尝试研究方法,也不会比较方法签名。

    Or to put it differently: Java doesn't support duck typing . 或者换句话说:Java不支持鸭子类型

  2. Usually, interfaces are used to make a bunch of classes easily interchangeable. 通常,接口用于使一堆类易于互换。 So you have something that needs a certain functionality. 因此,您需要某些功能。 Instead of typing this to a single class, you can use an interface. 您可以使用接口,而不是将其键入单个类。 People using that service can then feed it with different classes, according to their needs, making the service much more flexible (and somewhat harder to understand). 然后,使用该服务的人们可以根据他们的需求为它提供不同的类,从而使该服务更加灵活(并且有些难以理解)。

  3. It means you can use BaseB in any place where InterfaceName is expected. 这意味着您可以在需要InterfaceName任何地方使用BaseB That makes BaseB (and everything derived from it) much more useful/powerful. 这使BaseB (及其衍生的一切)变得更加有用/强大。

Example: 例:

If you want to check passwords, you can write a PasswordService class. 如果要检查密码,可以编写一个PasswordService类。 But that means everyone has to use this class and live with the limitations. 但这意味着每个人都必须使用此类,并要忍受这些限制。

If you offer a PasswordService interface, then users of your code can have different implementations: They can get passwords from a file, a database, LDAP, ... or for unit tests, they can write a service that says yes or no to every password. 如果提供了PasswordService接口,则代码的用户可以具有不同的实现:他们可以从文件,数据库,LDAP等获得密码,或者对于单元测试,可以编写对每个消息都表示“是”或“否”的服务。密码。

what difference having the keyword implements InterfaceName in class declaration make? 在类声明中使用关键字实现InterfaceName有什么区别?

You can then cast to that interface. 然后,您可以投射到该界面。

Java is not duck-typed. Java不是鸭式的。

Even if your class has a method void run() like a Runnable , you still won't be able to give it to places that want a Runnable without implementing the interface. 即使您的类具有像Runnable这样的void run()方法,如果没有实现该接口,您仍然无法将其提供给需要Runnable地方。

 new Thread(instanceOfMyNotRunnableClass);  // won't compile
  1. Two classes are not same by their code. 两个类的代码不同。 The code may be same but classes are still different. 代码可能相同,但类仍然不同。 Two classes with same code may behave similar but will not be same. 具有相同代码的两个类的行为可能相似,但不会相同。

  2. To understand purpose of Interface, you should understand concepts of Abstraction and Encapsulation. 要了解接口的目的,您应该了解抽象和封装的概念。 Interface not only provides a contract, also provides an abstraction over underlying classes. 接口不仅提供协定,还提供对基础类的抽象。 You may write an API that takes object of type Interface without bothering about actual class implementing the Interface. 您可以编写一个采用接口类型的对象的API,而不必担心实现接口的实际类。

  3. You can use BaseB in place where InterfaceName but you should not. 您可以在InterfaceName所在的位置使用BaseB,但不应使用。 This makes your code rigid for using only BaseB, whereas you may write an utility that takes any class that has implemented the interface. 这使您的代码仅使用BaseB变得僵硬,而您可以编写一个实用程序,该实用程序采用任何已实现接口的类。

Well, I assume that SomeInterface declares "doSomething", right? 好吧,我假设SomeInterface声明了“ doSomething”,对吗?

If that's the case, the benefit for you is that you can treat BaseB as SomeInterface. 在这种情况下,对您的好处是您可以将BaseB视为SomeInterface。 Let's say you have another class BaseC, which also implements SomeInterface, then this code is valid: 假设您还有另一个类BaseC,它也实现了SomeInterface,则此代码有效:

SomeInterface inter = new BaseB();
inter = new BaseC();

while this is not valid: 虽然这是无效的:

SomeInterface interr = new BaseA();

Your advantage is, that you do not have to know, if inter is BaseB() or BaseC(), because you simple work on the interface declared methods, no matter how the implementation excatly looks like. 您的优点是,不必知道inter是BaseB()还是BaseC(),因为无论实现的外观如何,您都可以轻松地对接口声明的方法进行操作。

Interface is used to make skeleton of your API. 接口用于制作API的框架。 Like java.util.ArrayList and java.util.LinkedList both are classes which implement interface java.util.List. 像java.util.ArrayList和java.util.LinkedList一样,都是实现接口java.util.List的类。

So if you have method like below 所以,如果你有下面的方法

void doSomething(java.util.List list){

}

You can pass java.util.ArrayList or java.util.LinkedList as per your requirment with no harm.You don't have to create two diff. 您可以根据需要传递java.util.ArrayList或java.util.LinkedList,而不会造成任何伤害。您不必创建两个diff。 methods where one accept java.util.ArrayList and another accept java.util.LinkedList 一个方法接受一个java.util.ArrayList,另一个接受java.util.LinkedList

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

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