Abstract class
An abstract class is a class that is not intended to be instantiated. Abstract classes may not have an implementation, some implementation, or an entire implementation. Abstract classes are designed to ensure that its subclasses have a common (default) implementation. A (pseudo-encoded) abstract class example would be something like this
abstract class Shape { def abstract area();
Subclass might look like
class Rectangle extends Shape { int height = width = 5; def override area() = { return height * width; }
Possible use
def main() = { Shape[] shapes = { new Rectangle(), new Oval() }; foreach (s in shapes) { print("area: " + s.area() + ", outline width: " + s.outline_width()); } }
If a subclass does not override unrealized methods, it is also an abstract class.
Interface
In general terms of computer science, an interface is part of a program open to the client. Public classes and members are examples of interfaces.
Java and C # have a special interface keyword. This is a more or less abstract class without implementation. (There is complexity about constants, nested classes, an explicit implementation, and access modifiers, which I am not going to enter.) Although the part about the "lack of implementation" is no longer suitable for Java, they added default methods. The interface keyword can be seen as a confirmation of the concept of an interface.
Returning to the example form
interface Shape { def area(); // implicitly abstract so no need for abstract keyword def outline_width(); // cannot implement any methods } class Rectangle implements Shape { int height = width = 5; def override area() = { return height * width; } def override outline_width() = { return 1; } // every method in interface must be implemented } def main() = { Shape[] shapes = { new Rectangle(), new Oval() }; foreach (s in shapes) { print("area: " + s.area() + ", outline width: " + s.outline_width()); } }
Java and C # do not allow multiple inheritance of classes with implementation, but they allow you to implement several interfaces. Java and C # use interfaces as a workaround for the Deadly Diamond of Death Problem , found in languages that allow multiple inheritance (which is actually not fatal if properly handled).
Mixin
A mixin (sometimes called a feature) allows multiple inheritance of abstract classes. Mixins do not have a terrible association that multiple inheritance has (due to the craziness of C ++), so it’s more convenient for people to use them. They have the exact same Deadly Diamond of the problem of death, but the languages that support them have more elegant ways to mitigate it than C ++, so they are perceived as better.
Mixers are welcome as behavioral reuse interfaces, more flexible and more powerful interfaces. You will notice that they all have the term interface in them, referring to the Java and C # keywords. Mixers are not interfaces. This is multiple inheritance. With a more beautiful name.
This does not mean that mixins are bad. Multiple inheritance is not bad. The way C ++ allows multiple inheritance is what everyone cares about.
On a tired, old form example
mixin Shape { def abstract area(); def outline_width() = { return 1; } } class Rectangle with Shape { int height = width = 5; def override area() = { return height * width; } } def main() = { Shape[] shapes = { new Rectangle(), new Oval() }; foreach (s in shapes) { print("area: " + s.area() + ", outline width: " + s.outline_width()); } }
You will notice that there is no difference between this and the abstract class example.
One additional tidbit is that C # supports mixins from version 3.0. You can do this using extension methods on interfaces. Here is an example of a form with real (!) C # mixin style code
interface Shape { int Area(); } static class ShapeExtensions { public static int OutlineWidth(this Shape s) { return 1; } } class Rectangle : Shape { int height = 5; int width = 5; public int Area() { return height * width; } } class Program { static void Main() { Shape[] shapes = new Shape[]{ new Rectangle(), new Oval() }; foreach (var s in shapes) { Console.Write("area: " + s.Area() + ", outline width: " + s.OutlineWidth()); } } }