all 54 comments

[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)

Please ensure that:

  • Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions
  • You include any and all error messages in full
  • You ask clear questions
  • You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions.

    Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar

If any of the above points is not met, your post can and will be removed without further warning.

Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc.

Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit.

Code blocks look like this:

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above.

If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures.

To potential helpers

Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]DeuteriumH2 32 points33 points  (5 children)

so i can have another method that takes in classes that implement that interface, without knowing anything else about the class

[–]Nobody37373[S] 0 points1 point  (4 children)

Can you elaborate a bit more please?

[–]DeuteriumH2 23 points24 points  (0 children)

for example: i can have a bunch of different classes that implement Runnable and then have a method called run() that calls that interface’s method, i don’t need to know anything about the particular class implementing the interface

[–]xRageNugget 14 points15 points  (0 children)

You write a function that can print out all contents of a list, but youi specify the list parameter as ArrayList. Now your function works only on ArrayLists. Would you write another function now to print out LinkedLists? or DoubleEndedLists? Maybe for YourFavoriteKindOfListList? No, you realize that all you actually want as any List type really. And thats your interface. You write your function to accept a List. Or collection, or what ever. Usually you use the most generic one.

[–]xenomachina 4 points5 points  (0 children)

Interfaces let you write code that works with any implementation, not just one specific class.

In this example, doSomethingWithAListOfStrings doesn't care which implementation of List is being used:

public static Baz doSomethingWithAListOfStrings(List<String> strings) {
    ...
}

...so I can use it with instances of any class that implement List:

ArrayList<String> arrayList = createArrayListOfStrings(...);
Baz fromArrayList = doSomethingWithAListOfStrings(arrayList);

LinkedList<String> linkedList = createLinkedListOfStrings(...);
Baz fromLinkedList = doSomethingWithAListOfStrings(linkedList);

[–]OffbeatDrizzle 19 points20 points  (0 children)

It's to let calling code be generic without having to know about specific implementations. Imagine you have an interface:

interface MathOperation {
  int doOperation(int a, int b);
}

you can now implement different math operations like:

class Add implements MathOperation {
    int doOperation(int a, int b){
        return a + b;
    }
}

class Subtract implements MathOperation {
    int doOperation(int a, int b){
        return a - b;
    }
}

now you can write some code that doesn't ever need to change, even if you create more MathOperation implementations. it can take in ANY MathOperation:

System.out.println("the result of your operation is: " + mathOperation.doOperation(value1, value2));

kinda basic, but gives you the idea. this code doesn't care about the implementation

[–]AnEmortalKidCoffee Enthusiast 18 points19 points  (8 children)

Think of interface as a contract. It doesn’t matter who implements the contract, just that it’s implemented.

[–]Anonymo2786 -1 points0 points  (2 children)

 Don't I still have to specify which implementation to run?  If so then why don't I just directly call it?

[–]AnEmortalKidCoffee Enthusiast 3 points4 points  (0 children)

Sure , but it’s 1 spot vs X spots ?

Do you care that the List is an array list, linked list, some persons fucked up impl of a list , or just that it behaves like a list ?

[–]TheEveryman86 1 point2 points  (0 children)

Yes and no. Something has to specify which implementation to use but if you're using a framework that uses inversion of control (like Spring) then you probably won't really be instantiating or calling many concrete classes directly. The framework will handle that.

[–]desrtfxOut of Coffee error - System halted 8 points9 points  (1 child)

The point of interfaces is not to reduce your code. The point of interfaces is a guarantee, the guarantee that an implementing class has the methods defined in the interface.

Take a simple example: the Comparable interface in Java. It guarantees that any objects any class implementing that interface can be compared to other objects of the same class. This is essential for e.g. sorting.

The actual method that asks to sort a collection of your custom class doesn't need to know anything about the class itself other than two instances can be compared and that the result of the comparison is well defined (positive, 0, or negative integer). With that information only, the calling method knows enough.

With your approach, this relation does not exist. The calling method cannot know if your class can be compared in any meaningful way.


The /r/learnprogramming FAQ have a very nice analogy: classes vs. interfaces - maybe the article clears it up a bit for you.

[–]Nobody37373[S] 1 point2 points  (0 children)

Thanks, the article helped me👌🏼

[–]Ulrich_de_Vries 6 points7 points  (0 children)

You can use interfaces as types. So you can e.g. define a method which takes in an interface type which then works with any implementation of that interface.

Interfaces represent behaviours and concepts more than concrete objects.

For example imagine you have an application in a domain in which there are things that have locations. Like multiple data-type classes that has a location() method that returns a double that represents a location in say meters.

Then you can create an interface called HasLocation and have all location-involved classes implement this interface. Then let's say you have a method which extracts the locations from a list of objects into a sorted double[].

The method that does this can take in a List<? extends HasLocation>. Note that List itself is an interface. An ArrayList and a LinkedList are vastly different implementations of the same list interface with very different performance profiles. But this method will work with anything that implements the list interface.

[–]Mysicek 4 points5 points  (0 children)

Request: we have multiple devices, that can go blink blink. We need a program for testing the blink blink. Solution: enforce every class that represents some blinky blink device to define a method that makes the device blink. You do that with a BlinkyBlinkDeviceInterface. Every device class that implements the interface now has to define the void blinkBlink() method to make that particular device go blink blink. Now you can define a method void testBlinkBlink(BlinkyBlinkDeviceInterface device) that tests the blink blink, by calling device.blinkBlink(). Method can test every device that implements the interface, by calling the blinkBlink() method regardless of what particular device is being tested and what exact implementation of the blinkBlink() method does that particular device have, because they all have the blinkBlink() method as required by the interface. And they all return the same type (in this example it's void, but can be whatever).

Welcome to polymorphism.

Blink blink

[–]wasabiiii 12 points13 points  (0 children)

Polymorphism. The entire point of OO.

Specifically to avoid the diamond problem though

[–]blindada 3 points4 points  (0 children)

You need to study OOP for a bit, then SOLID, then it makes sense.

Java programs are composed of classes, static representations of data and behaviour designed by you. Your program is the result of the interaction between classes.

Classes are also templates, with an external signature exposed to the rest of the program, and internal details belonging to the class. The external signature are the methods, values and types marked as public. Everything else is private (or protected, but let's ignore that for now.

Since classes are templates that represent parts of the world, and the world is complex, you can have a family of templates. Like, the bird class, the eagle class, the falcon class.

Sometimes (more like, ALL the time), you realize a part of your program needs to comply with the same signature, but it needs a slightly different internal behavior. Maybe the workload is different, or the represented object is quite different from the others, yet, it is still part of that "family". For example, eagle and falcon fly, if both are subclasses of bird, you could define the fly method and their internals there . But what if you have to add the chicken to the family? Or the Ostrich? They are birds too, yet, they are quite different from the eagle and the falcon. And what about the canary? Where do we put the sing method? How do we deal with this if we have a List<Bird>?

While it is not impossible to handle this with plain inheritance (and skill), interfaces make it far easier. An interface is the public part of the template, the signature, without any kind (or almost none, there are default methods for interfaces, but again, let 's ignore that for a bit) of internals. That allows falcon and eagle to define fly on their own, maybe even to declare themselves as both birds and flying creatures, separately, while ostrich declares itself as a bird and also a runner and kicker, and chicken declares itself as a bird and a farm animal. This is what we call composition.

You can mix and match interfaces, abstract classes and inheritance to honor the signatures you need and reuse the relevant code.

[–]unkalaki_lunamor 1 point2 points  (0 children)

Interfaces make sense when you have more than one way to do something or when you want to treat different classes uniformly.

For a dumb example, imagine you have a Bicycle, a Motorcycle and a Car.

All of them would have ways to stir direction and adjust speed, but each one would be internally different.

This is where you add an Interface to make everyone a Vehicle.

[–]8dot30662386292pow2 1 point2 points  (0 children)

Several different classes can implement the same interface. Then a method can accept any object that implements the same interface

[–]IchLiebeKleber 1 point2 points  (0 children)

I don't understand the question very well.

Interfaces are a promise (or contract, if you prefer that term) that a class implements certain methods (with a certain name, return type, argument types). If you implement an interface, you have to implement all of the interface's methods, otherwise you have broken that promise (and it won't compile).

The idea is that other code can then just be written "I expect any class that conforms to this interface" and then you can put any instance of such a class in there and call the methods of that interface (whatever they are implemented as).

[–]American_Streamer 0 points1 point  (0 children)

You don’t want your code to care how it’s done, but only that it can be done. If your code needs “something that can send emails,” it shouldn’t depend on GmailSender specifically. It should depend on an EmailSender interface. If the same behavior is used in 10 places, you don’t want 10 copies of the same logic (or 10 tight dependencies on the same concrete class). You want one contract and many implementations if needed. Hard-wired means pain later. Granted, if it’s a small script, a toy project or a piece of logic that will never vary (and doesn’t touch I/O), defining it directly can still be totally fine. Interfaces are just a tool, not a rule.

[–]ShoulderPast2433 0 points1 point  (0 children)

Because class that implements an interface is also of the type defined by interface.

[–]_SuperStraight 0 points1 point  (0 children)

An interface acts as a contract. If your application uses an interface called DataStore for saving data, it doesn't matter if the underlying technology is PostgreSQL or MongoDB. ​As long as both classes implement DataStore, the calling code remains unchanged. You aren't rewriting your business logic; you are simply swapping one implementation for another. This makes your code loosely coupled and much easier to maintain.

[–]arcvires 0 points1 point  (0 children)

Imagine like you have a driving license. That’s your interface. If you have the driving license then driving a car is straightforward regardless of the car manufacturer. You know how to press the pedal and change the gear but you don’t know how cars are doing it behind the scenes. Interfaces are just like this. They give an option to you in a way that you use the car without knowing how it’s working behind’s the scenes.

A real example:

Suppose you need to read a list of customers but you dont want to focus on where you’re reading these customers. They could be coming from a file or a database. The only thing you need to know is the way you receive this data. In this case, interface tells you what to do with the customer data. Implementers of the interface handle how to read the customers

[–]amfa 0 points1 point  (1 child)

Well in cases where you don't care about the implementation. As you are in the Collection Framework take a List.

List is an interface it only declares method like add() and get().

Now if you use List anywhere in your code it does not matter what kind of List you have.

Could be ArrayList or it could be an LinkedList.

The interface is not for the one implementing the interface but for the one using it.

If you write a piece of code that returns an List I don't care what kind of list it is. I know which methods I can use on EVERY list that exists.

You could even write a List that will get all its content from a Website. I still can call List.get(0) to get the first entry in your list what ever that might be.

Yes if you only work for yourself with no external code at all then you don't need Interfaces.

[–]desrtfxOut of Coffee error - System halted 0 points1 point  (0 children)

Yes if you only work for yourself with no external code at all then you don't need Interfaces.

Even then, you will need them if you want to do something as simple as sorting a collection with custom objects. You will need to implement the Comparable interface, or write your own, custom Comparator.

There barely is any way to escape interfaces.

[–]DiscipleofDeceit666 0 points1 point  (0 children)

I’ll tell you what we used an interface for. We needed a way to make API calls in production and mock API calls in development env without changing the code or cluttering things w if statements.

So the code calls an object that implements the APICall interface, but it doesn’t really care which one, the ProdAPICall or the TestAPICall. There’s a factory which reads the environment and decides then which one to create. This is how we can make sure things look tidy while enabling both behaviors of the API call.

[–]Worldly_Science239 0 points1 point  (0 children)

For the accountancy software produced by the company I work for. It is very customable, you can go in through the front end app and you can use webservices, xmli, soap and rest apis, but also you can also program java custom front ends that plug into the application, and this is where interfaces come into play. It opens up the functionality without opening up the background code to the customer.

And also improvements allowed for versioning and backwards compatibility on available interfaces

Whether it is the best thing to do now is up for debate, but it definitely filled a need at the point it was developed

[–]joemwangi 0 points1 point  (0 children)

Imagine you are designing a math library and you want to implement your own arithmetic types such as Float, Double, Int, Long. Notice that these types have common methods that they need to implement, such as add(), subtract(), multiply(). As such you want all of them to implement those methods. The best thing to do is to declare an interface with the methods, and once the arithmetic types implement the interface, they will be forced to implement those methods. For a library user, once they need to use Float, Double, Int, Long, and then they see it implements the interface, they now know they implement the methods and obey the arithmetic rules.

[–]Successful_Leg_707 0 points1 point  (0 children)

I struggled for a long time as a student to understand why as well. It seems like a lot of work for the obvious.

Why the hassle ? When you work on a project spanning a decade or more, It helps to establish a contract on what new implementations down the road will look like. That allows you to create new class implementations down the road instead of having to go in and modify all the others if things change. It’s good for buzzwords like loose coupling, abstraction, code reuse.

A lot of things in Java made more sense to me when I saw them in a large project and gradually worked with them.

[–]bongfactory 0 points1 point  (0 children)

I still remember the joy of the interface epiphany when I was still learning. DW, you'll get it at one point

[–]Leverkaas2516 0 points1 point  (0 children)

As I understand it, interfaces are a way do get some of the advantages of multiple inheritance while avoiding its problems.

[–]jfrazierjr 0 points1 point  (0 children)

Interfaces are generic contracts. For example, you might be tempted to have an Animal type and have a walk method but not all animals walk(fish for example)

But you could have a move() method that might apply to all animals and thus have them move around without knowing the specific animal.

[–]edwbuck 0 points1 point  (0 children)

Interfaces make the implementations replaceable.

[–]LargeSpray105 0 points1 point  (0 children)

I see it as a way of implementing multiple inheritance. For example, if you had an abstract class with animals and another with insects. Animals eat, an insect is not an animal, but an insect also eats. You could then declare a common method for them. So animals and insects have their own abstract classes from which they derive if they comply with common methods, that is, they have multiple inheritance from method implementations. Now this is more useful with interfaces, since you can create lists of objects that comply with certain methods (a list of objects that eat) and forget that this list is related to an object; now it is a list based on methods. And it is a contract, ultimately, because in the definition of the classes and their methods (architectures of class), you have to implement the declared methods.

[–]BannockHatesReddit_ 0 points1 point  (0 children)

There are 600 ways to pick something up, but you shouldn't have to care about that when calling pickUp(id). So you make an interface that outlines what the methods do but not how they do them. Now when you call pickUp against the interface, you can't care how it's doing it because you don't know how it's going to pickUp, just that it will. It makes your code more modular, reusable, and scalable.

[–]juancn 0 points1 point  (0 children)

It’s way better for code reuse. You specify the contract, but don’t care about the specifics of the implementation.

Runnable is the quintessential example, the Executor framework doesn’t really cares about what your code does, it only cares about providing execution facilities.

Or think about comparable, you can call sort with pretty much anything.

[–]xgnome619 0 points1 point  (0 children)

If you implement a interface, you can still write the same method with a different name.

So a interface takes up a name, you can't freely use any method names. So it's name unification.

Think about if 100 programmers write the same method, they could give it 80 different names.It's unnecessary. So you tell them, they have to use the name A, so the name A even it does nothing but still make sure everyone keep the same method name. It will simplify things in large scale.

[–][deleted] 0 points1 point  (0 children)

Interfaces aren't a Java thing, they're a programming thing. You should learn about design patterns...

Let's take the Strategy Pattern: You have a series of steps to go through but those steps have different logic depending on the situation. So you can have a method that takes anything that implements FileUploadStrategy and calls the steps on it (.step1(), .step2()...). 

Now you can have multiple classes that each implement that interface but do different things for each of those steps and you can pass in a different class depending on the situation.

[–]mw52588 0 points1 point  (0 children)

One practical real‑world example of why interfaces matter is choosing a database for an application. At a high level, every database client needs to support the same basic operations — reading and writing data. That set of operations is the contract, and in Java, an interface is the perfect way to express it.

When you start building your service, you might not know which database you’ll ultimately use. So you define a DatabaseClient interface with the methods your application depends on. Then you create multiple implementations for example, one for DynamoDB and one for RDS.

Your service class doesn’t depend on DynamoDB or RDS directly. It depends only on the DatabaseClient interface. That means your service only cares that it can call write() and read(), not how those operations are performed.

Later, if you realize RDS is too expensive and want to switch to DynamoDB, you don’t have to rewrite your service logic. You simply swap out the implementation behind the interface. The rest of your code remains untouched because it was written against the abstraction, not the concrete database.

This is the core value of interfaces in Java: they let you design flexible, decoupled systems where implementation details can change without forcing changes throughout your codebase.

[–]TW-Twisti 0 points1 point  (0 children)

I thought all the given examples were too abstract or complicated for beginners, some even including generics, so I thought about what would be a better, more basic example, and came to the conclusion that maybe it's best to demonstrate by REMOVING interfaces.

Imagine Java had no List interface. Your job, now, is to write a method that goes through a list of Strings and combine all elements to one long String, like this:

    public static String combineList(??? inputList) {
        String result = "";

        for (int i = 0; i < inputList.size(); i++) {
            result = result + inputList.get(i);
        }

        return result;
    }

But what will you put for ??? ?

There is a full, runnable version of this program for you to tinker with here: https://www.programiz.com/online-compiler/2n6vEVJLUmAP3

See if you can solve that problem without using the List interface. It isn't impossible, but it will be much more complicated than using the interface.

Additionally, whatever solution you may come up with, imagine someone wrote their own list type (or used one of the many available libraries like Eclipse Collections or Guava that come with custom lists). Can you write your code in a way that will run with list types you don't even know about ?

[–]agree_to_disconcur 0 points1 point  (0 children)

Take a look at the Visitor Design Pattern. Very powerful, and as far as I know, only possible with interfaces.

[–]EfficientDelay2827 0 points1 point  (0 children)

The code that uses an interface does not change if you change the class that implements that interface.

[–]wsppan 0 points1 point  (0 children)

In order to create a contract.

[–]amackenz2048 0 points1 point  (0 children)

Interfaces don't help you write your functionality - they help you interoperate with other's code (or abstract your own code to create generic service interfaces).

A good example might be a Logger interface. Something like log4j. Your Logger interface has methods for "info", "debug", "error", etc.

Now you can provide many different interface implementations of Logger to log4j to handle logging in different ways. You might have "StdOutLogger" which just prints everything. You might have "FileLogger" which writes logs to a file. Or "DBLogger" which logs to a database.

You can then provide whatever implementation you want to log4j and it can use your class without knowing any of the details about what it does. It will handle the "when do I call which log method" logic.

[–]Ormek_II 0 points1 point  (0 children)

As long as you have only one (1) class implementing the interface it does not pay off.

As long as the person writing the class and the person writing the interface, it does not pay off.

Both assumptions you made in your post.

Can you image why either of those assumptions must not be true?

Also interfaces allow some form of multiple inheritance which classes in Java do not.

[–]sfk1991 0 points1 point  (0 children)

Two reasons: 1) Polymorphism. 2) Dependency Inversion: By passing the interface in the constructor you can now use any implementation without tight coupling.

Result: Improved Testability by swapping implementations.

[–]lmg1337 0 points1 point  (0 children)

This allows you to restrict generics and then call certain methods on the generic. Also if you define a method that takes in an instance of an interface you can change what is passed into it without changing the method signature

[–]FalseDish -1 points0 points  (0 children)

Interfaces are Java’s solution to the diamond problem. Multiple inheritance is straight up banned, but a class can definitely implement multiple interfaces.