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.
Answer from Vimal Bera on Stack OverflowVideos
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.
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<>();
How about an analogy: when I was in the Air Force, I went to pilot training and became a USAF (US Air Force) pilot. At that point I wasn't qualified to fly anything, and had to attend aircraft type training. Once I qualified, I was a pilot (Abstract class) and a C-141 pilot (concrete class). At one of my assignments, I was given an additional duty: Safety Officer. Now I was still a pilot and a C-141 pilot, but I also performed Safety Officer duties (I implemented ISafetyOfficer, so to speak). A pilot wasn't required to be a safety officer, other people could have done it as well.
All USAF pilots have to follow certain Air Force-wide regulations, and all C-141 (or F-16, or T-38) pilots 'are' USAF pilots. Anyone can be a safety officer. So, to summarize:
- Pilot: abstract class
- C-141 Pilot: concrete class
- ISafety Officer: interface
added note: this was meant to be an analogy to help explain the concept, not a coding recommendation. See the various comments below, the discussion is interesting.
While your question indicates it's for "general OO", it really seems to be focusing on .NET use of these terms.
In .NET (similar for Java):
- interfaces can have no state or implementation
- a class that implements an interface must provide an implementation of all the methods of that interface
- abstract classes may contain state (data members) and/or implementation (methods)
- abstract classes can be inherited without implementing the abstract methods (though such a derived class is abstract itself)
- interfaces may be multiple-inherited, abstract classes may not (this is probably the key concrete reason for interfaces to exist separately from abtract classes - they permit an implementation of multiple inheritance that removes many of the problems of general MI).
As general OO terms, the differences are not necessarily well-defined. For example, there are C++ programmers who may hold similar rigid definitions (interfaces are a strict subset of abstract classes that cannot contain implementation), while some may say that an abstract class with some default implementations is still an interface or that a non-abstract class can still define an interface.
Indeed, there is a C++ idiom called the Non-Virtual Interface (NVI) where the public methods are non-virtual methods that 'thunk' to private virtual methods:
- http://www.gotw.ca/publications/mill18.htm
- http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface
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.
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
I like to think of interfaces as contracts (this object will have property X & Y and method Z) but makes no assumptions about implementation (at least they did before Default Interface Implementations as of C# 8: https://devblogs.microsoft.com/dotnet/default-implementations-in-interfaces, although I use these sparingly if ever).
Abstract classes (and derived non-sealed classes) can be thought of as just a place to share implementation that's common between supersets of classes and their subsets. Abstract classes provide an object-oriented way of supporting the Don't Repeat Yourself (DRY) principle (https://www.c-sharpcorner.com/article/software-design-principles-dry-kiss-yagni) where the implementation you would otherwise repeat doesn't make sense outside of the context of your class hierarchy.
Interfaces & abstract classes are by no means mutually exclusive and can be used in conjunction with each other depending on the context.
abstract classes are to define a common base class for inheritance, without implementing any actual methods.
because c# does not support multiple inheritance, interfaces are the solution. a class can inherit from one base class, but it can implement many interfaces. interfaces can only be implemented. an interface can not inherit from another interface.
due to issues with inheritance chains, inheritance is often considered an anti-pattern, interface design is recommend instead. with interface design you define contacts that define properties and methods. then classes must implement. other languages use protocols/traits which are slight more feature rich than interfaces.
one past advantage with classes, was you could define default behavior, and interfaces were abstract (no implementations). But modern C# allows default implemations for interfaces.
so my recommendation is to avoid class inheritance (and never more than 1 deep, that is only inherit from base), but rather use interfaces and extension methods to extend classes.
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.
In layman's terms:
Interfaces are for "can do/can be treated as" type of relationships.
Abstract ( as well as concrete ) classes are for "is a" kind of relationship.
Look at these examples:
class Bird extends Animal implements Flight;
class Plane extends Vehicle implements Flight, AccountableAsset;
class Mosquito extends Animal implements Flight;
class Horse extends Animal;
class RaceHorse extends Horse implements AccountableAsset;
class Pegasus extends Horse implements Flight;
Bird, Mosquito and Horse are Animals. They are related. They inherit common methods from Animal like eat(), metabolize() and reproduce(). Maybe they override these methods, adding a little extra to them, but they take advantage of the default behavior implemented in Animal like metabolizeGlucose().
Plane is not related to Bird, Mosquito or Horse.
Flight is implemented by dissimilar, unrelated classes, like Bird and Plane.
AccountableAsset is also implemented by dissimilar, unrelated classes, like Plane and RaceHorse.
Horse doesn't implement Flight.
As you can see classes (abstract or concrete) helps you build hierarchies, letting you inhering code from the upper levels to the lower levels of the hierarchy. In theory the lower you are in the hierarchy, the more specialized your behavior is, but you don't have to worry about a lot of things that are already taken care of.
Interfaces, in the other hand, create no hierarchy, but they can help homogenize certain behaviors across hierarchies so you can abstract them from the hierarchy in certain contexts.
For example you can have a program sum the value of a group of AccountableAssets regardless of their being RaceHorses or Planes.
You could deduce the answer logically since you seem to be aware of the differences between the two.
Interfaces define a common contract. Such as an interface called IAnimal, where all animals share functions such as Eat(), Move(), Attack() etc. While all of them share the same functions, all or most of them have a different way (implementation) of achieving it.
Abstract classes define a common implementation and optionally common contracts. For example a simple Calculator could qualify as an abstract class which implements all the basic logical and bitwise operators and then gets extended by ScientificCalculator, GraphicalCalculator and so on.
If you have common implementation then by all means, encapsulate the functionality in an abstract class to extend from. I have near 0 PHP experience, but i don't think you can create interfaces with non constant fields. If the fields are common between your instance classes then you are forced to use an Abstract class, unless you define access to them via getters and setters.
Also, there seems to be no shortage of results in Google.
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).