I wrote an article about that:
Abstract classes and interfaces
Summarizing:
When we talk about abstract classes we are defining characteristics of an object type; specifying what an object is.
When we talk about an interface and define capabilities that we promise to provide, we are talking about establishing a contract about what the object can do.
Answer from Jorge Córdoba on Stack OverflowI wrote an article about that:
Abstract classes and interfaces
Summarizing:
When we talk about abstract classes we are defining characteristics of an object type; specifying what an object is.
When we talk about an interface and define capabilities that we promise to provide, we are talking about establishing a contract about what the object can do.
An abstract class can have shared state or functionality. An interface is only a promise to provide the state or functionality. A good abstract class will reduce the amount of code that has to be rewritten because it's functionality or state can be shared. The interface has no defined information to be shared
java - When should i use an abstract class vs an interface? - Software Engineering Stack Exchange
When to use an interface versus an abstract class?
What is the main diffrence between AbstractClass and ...
What is the difference between interface and abstract class - Programming & Development - Spiceworks Community
Videos
Note: please forgive the C# syntax, but the principle of the answer is the same for Java and C#.
Now when i started programming I noticed that in all subclasses i basically needed to do the exact same thing
Based on this, it seems like you think abstract classes are only allowed to declare abstract methods. This is not the case.
An abstract class is a class that cannot be instantiated directly (only its derivations can be instantiated). An abstract method is a method in an abstract class which must be implemented in the derived class.
But an abstract class can have non-abstract methods:
public abstract class Artikel
{
public int ArtikelId { get; set; }
public string SayHello()
{
return "Hi, I'm artikel " + ArtikelId;
}
}
When you derive Artikel into subclasses, you do not need to repeat the method body of the SayHello method. Its body has been declared in the base class and can be used by all of the derived classes.
I thought of making Artikel not abstract and put an interface between Artikel and the other classes
Interfaces prevent the ability to create a common method body. If you were to use an interface:
public interface IArtikel
{
string SayHello();
}
Then you will be required to implement this method separately in every class:
public class Book : IArtikel
{
public string SayHello()
{
// custom book logic
}
}
// And the same for all other derived classes.
It's also possible to make an seperate class which inherits from Artikel where I can put all the methods, but then there the methods would still be needed to made three times, one for each subclass right?
Don't take this the wrong way, but your attempts at solving this suggest you don't really master OOP. If this SeparateClass was created as another (4th) subclass from Artikel, how would you expect e.g. the Book class to rely on the methods found in SeparateClass?
Is it a bad design choice if I keep Artikel as abstract?
Keep Artikel abstract, but give it non-abstract methods (i.e. with method bodies) for each method that you are now copy/pasting between all of its subclasses.
You can have a base class as an abstract class which implements the Artikel interface. In the abstract class you can define the common implementation. Then you can derive LP, Book and Boardgame from that super class. In my opinion it is better to have a abstract class rather than copying the same code in all 3 sub classes.
I understand that the interface is used to decouple the abstraction from the implementation. As a very common example you will see with a List and an ArrayList.
List<String> interfaceList = new ArrayList<>();
You can swap out the List implementation with any other class that implements the interface.
Same thing with abstract classes. So is there a reason why you don't see this?
AbstractList<String> abstractList = new ArrayList<>();