The general age-old principle is: Stick with interfaces until you're forced to write an abstract class.
An interface in Java is a non-instantiable type which defines a public interface that other types can choose to conform to.
- Interfaces can declare public methods, which must be defined by their implementors. All such methods are implicitly
abstract, so you don't need to use the wordabstract. - In old versions of Java, interfaces could not have default implementations, so every method was
abstract. This is no longer the case, and interfaces can now have default implementations that get used inimplementing classes unless replaced. - In recent versions of Java, interfaces can declare
privatehelper methods. These can help in implementing default implementations. - Interfaces can never have constructors or instance variables.
- A class can
implementseveral interfaces.
An abstract class is just a class that cannot be instantiated. Abstract classes are not required to define any abstract methods, though you'll usually want to.
- Abstract classes can declare methods with any visibility:
public,private,protected, and package-private. - Abstract classes can implement methods or leave them
abstract. Methods in an abstract class are not implicitlyabstractand must be marked as such. - An abstract class can have constructors, which must be called by
extending classes in their own constructor usingsuper. An abstract class can have instance variables of any visibility, and these work just like instance variables in any parent class. - A class can only
extendone class, either anabstractone or a concrete one. A class'abstractness does not change the number of superclasses it's allowed to have.
abstract classes should be the exception and not the norm. You should use an abstract class if you need to maintain some internal state while also letting subclasses define your own behavior. A great example of this comes from the Java Swing GUI library: AbstractButton. AbstractButton is the abstract parent of things that behave vaguely like buttons in a window, including buttons, toggle buttons, and items in a menu. Anyone can subclass AbstractButton and implement its members to define a button-like display. But AbstractButton also has to maintain a lot of internal state (much of it coming from JComponent) in order to communicate with the window and with the Swing API as a whole.
If you want to define the public interface for a collection of types, use an interface. If you want to provide default implementations for some of those methods and are using a version of Java released after 2014, use interfaces. If you need default implementations but are stuck in the 2000s, use an abstract class. Regardless of Java version, if you need private state such as instance variables or custom initialization like a constructor, use an abstract class.
java - When to use abstraction and when an interface? - Stack Overflow
What is the difference between an Interface and an Abstract class?
In terms of code, they're very similar, which often raises confusion like yours.
Conceptually, I think of it this way. When you inherit from an abstract class, you're saying that you are a type of the class. You have the same attributes.
When you implement an interface, you're saying that you do the things that that interface does.
In one sentence, abstract classes allow you to inherit state/variables/data, interfaces allow you inherit behaviors.
More on reddit.comoop - What is the difference between an interface and abstract class? - Stack Overflow
Abstraction vs abstract class/interfaces - Java - Code with Mosh Forum
The general age-old principle is: Stick with interfaces until you're forced to write an abstract class.
An interface in Java is a non-instantiable type which defines a public interface that other types can choose to conform to.
- Interfaces can declare public methods, which must be defined by their implementors. All such methods are implicitly
abstract, so you don't need to use the wordabstract. - In old versions of Java, interfaces could not have default implementations, so every method was
abstract. This is no longer the case, and interfaces can now have default implementations that get used inimplementing classes unless replaced. - In recent versions of Java, interfaces can declare
privatehelper methods. These can help in implementing default implementations. - Interfaces can never have constructors or instance variables.
- A class can
implementseveral interfaces.
An abstract class is just a class that cannot be instantiated. Abstract classes are not required to define any abstract methods, though you'll usually want to.
- Abstract classes can declare methods with any visibility:
public,private,protected, and package-private. - Abstract classes can implement methods or leave them
abstract. Methods in an abstract class are not implicitlyabstractand must be marked as such. - An abstract class can have constructors, which must be called by
extending classes in their own constructor usingsuper. An abstract class can have instance variables of any visibility, and these work just like instance variables in any parent class. - A class can only
extendone class, either anabstractone or a concrete one. A class'abstractness does not change the number of superclasses it's allowed to have.
abstract classes should be the exception and not the norm. You should use an abstract class if you need to maintain some internal state while also letting subclasses define your own behavior. A great example of this comes from the Java Swing GUI library: AbstractButton. AbstractButton is the abstract parent of things that behave vaguely like buttons in a window, including buttons, toggle buttons, and items in a menu. Anyone can subclass AbstractButton and implement its members to define a button-like display. But AbstractButton also has to maintain a lot of internal state (much of it coming from JComponent) in order to communicate with the window and with the Swing API as a whole.
If you want to define the public interface for a collection of types, use an interface. If you want to provide default implementations for some of those methods and are using a version of Java released after 2014, use interfaces. If you need default implementations but are stuck in the 2000s, use an abstract class. Regardless of Java version, if you need private state such as instance variables or custom initialization like a constructor, use an abstract class.
Interfaces:
Say you have an interface, like:
interface Animal {
String makeNoise();
}
and a couple of classes that implement Animal:
class Cat implements Animal {
String makeNoise() {
return "Meow";
}
}
class Dog implements Animal {
String makeNoise() {
return "Woof";
}
}
Now you can use the interface as the return type, so a method can return a Cat or a Dog.
String makeAnimalMakeNoise(int animalId) {
Animal animal = pretendAnimalService.getDogOrCat(animalId);
animal.makeNoise();
}
Abstract Classes:
Let's say you have an abstract class:
abstract class Animal {
public String makeNoise() {
return "Whistle";
}
abstract public String getName();
}
Now, any class that extends this would need to implement the getName method:
class Cat extends Animal {
String getName() {
return "Pussy";
}
}
class Dog extends Animal {
String getName() {
return "Fido";
}
}
Both of the above classes implemented the required getName method, but they also have access to the parent classes makeNoise method, which can also be overridden if required.
It's important to note the other differences too, which are:
- You can only extend one abstract class but you may implement multiple interfaces.
- Interfaces should be used when different types should have the same method signature whereas abstract classes should be used when implementations share a common behaviour.
- They are not mutually exclusive.
- An interface can only have public methods where as abstract classes can have public and protected methods.
Abstract classes may contain function definitions yes, but if you make every function in the class abstract doesn't that essentially make it the exact same thing as an interface?
Obviously Interfaces are different in some capacity otherwise they wouldn't exist. What am i missing here? Why would you ever use an interface instead of an abstract class?
In terms of code, they're very similar, which often raises confusion like yours.
Conceptually, I think of it this way. When you inherit from an abstract class, you're saying that you are a type of the class. You have the same attributes.
When you implement an interface, you're saying that you do the things that that interface does.
In one sentence, abstract classes allow you to inherit state/variables/data, interfaces allow you inherit behaviors.
Abstract classes may contain function definitions
This answers your question.
if you make every function in the class abstract doesn't that essentially make it the exact same thing as an interface?
Yes.
Why would you ever use an interface instead of an abstract class?
Because a class can implement multiple interfaces, but only extends a single (abstract) class.
Interfaces
An interface is a contract: The person writing the interface says, "hey, I accept things looking that way", and the person using the interface says "OK, the class I write looks that way".
An interface is an empty shell. There are only the signatures of the methods, which implies that the methods do not have a body. The interface can't do anything. It's just a pattern.
For example (pseudo code):
// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();
int getFuel();
}
// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{
int fuel;
void run()
{
print("Wrroooooooom");
}
int getFuel()
{
return this.fuel;
}
}
Implementing an interface consumes very little CPU, because it's not a class, just a bunch of names, and therefore there isn't any expensive look-up to do. It's great when it matters, such as in embedded devices.
Abstract classes
Abstract classes, unlike interfaces, are classes. They are more expensive to use, because there is a look-up to do when you inherit from them.
Abstract classes look a lot like interfaces, but they have something more: You can define a behavior for them. It's more about a person saying, "these classes should look like that, and they have that in common, so fill in the blanks!".
For example:
// I say all motor vehicles should look like this:
abstract class MotorVehicle
{
int fuel;
// They ALL have fuel, so lets implement this for everybody.
int getFuel()
{
return this.fuel;
}
// That can be very different, force them to provide their
// own implementation.
abstract void run();
}
// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}
Implementation
While abstract classes and interfaces are supposed to be different concepts, the implementations make that statement sometimes untrue. Sometimes, they are not even what you think they are.
In Java, this rule is strongly enforced, while in PHP, interfaces are abstract classes with no method declared.
In Python, abstract classes are more a programming trick you can get from the ABC module and is actually using metaclasses, and therefore classes. And interfaces are more related to duck typing in this language and it's a mix between conventions and special methods that call descriptors (the __method__ methods).
As usual with programming, there is theory, practice, and practice in another language
The key technical differences between an abstract class and an interface are:
Abstract classes can have constants, members, method stubs (methods without a body) and defined methods, whereas interfaces can only have constants and methods stubs.
Methods and members of an abstract class can be defined with any visibility, whereas all methods of an interface must be defined as
public(they are defined public by default).When inheriting an abstract class, a concrete child class must define the abstract methods, whereas an abstract class can extend another abstract class and abstract methods from the parent class don't have to be defined.
Similarly, an interface extending another interface is not responsible for implementing methods from the parent interface. This is because interfaces cannot define any implementation.
A child class can only extend a single class (abstract or concrete), whereas an interface can extend or a class can implement multiple other interfaces.
A child class can define abstract methods with the same or less restrictive visibility, whereas a class implementing an interface must define the methods with the exact same visibility (public).
I will give you an example first:
public interface LoginAuth{
public String encryptPassword(String pass);
public void checkDBforUser();
}
Suppose you have 3 databases in your application. Then each and every implementation for that database needs to define the above 2 methods:
public class DBMySQL implements LoginAuth{
// Needs to implement both methods
}
public class DBOracle implements LoginAuth{
// Needs to implement both methods
}
public class DBAbc implements LoginAuth{
// Needs to implement both methods
}
But what if encryptPassword() is not database dependent, and it's the same for each class? Then the above would not be a good approach.
Instead, consider this approach:
public abstract class LoginAuth{
public String encryptPassword(String pass){
// Implement the same default behavior here
// that is shared by all subclasses.
}
// Each subclass needs to provide their own implementation of this only:
public abstract void checkDBforUser();
}
Now in each child class, we only need to implement one method - the method that is database dependent.
Nothing is perfect in this world. They may have been expecting more of a practical approach.
But after your explanation you could add these lines with a slightly different approach.
Interfaces are rules (rules because you must give an implementation to them that you can't ignore or avoid, so that they are imposed like rules) which works as a common understanding document among various teams in software development.
Interfaces give the idea what is to be done but not how it will be done. So implementation completely depends on developer by following the given rules (means given signature of methods).
Abstract classes may contain abstract declarations, concrete implementations, or both.
Abstract declarations are like rules to be followed and concrete implementations are like guidelines (you can use it as it is or you can ignore it by overriding and giving your own implementation to it).
Moreover which methods with same signature may change the behaviour in different context are provided as interface declarations as rules to implement accordingly in different contexts.
Edit: Java 8 facilitates to define default and static methods in interface.
public interface SomeInterfaceOne {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
}
}
Now when a class will implement SomeInterface, it is not mandatory to provide implementation for default methods of interface.
If we have another interface with following methods:
public interface SomeInterfaceTwo {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
}
}
Java doesn’t allow extending multiple classes because it results in the “Diamond Problem” where compiler is not able to decide which superclass method to use. With the default methods, the diamond problem will arise for interfaces too. Because if a class is implementing both
SomeInterfaceOne and SomeInterfaceTwo
and doesn’t implement the common default method, compiler can’t decide which one to chose. To avoid this problem, in java 8 it is mandatory to implement common default methods of different interfaces. If any class is implementing both the above interfaces, it has to provide implementation for defaultMethod() method otherwise compiler will throw compile time error.