Abstract classes versus interfaces versus mixins

Can someone explain to me the differences between abstract classes , interfaces and mixins ? I used each in my code, but I do not know the technical differences.

+44
oop terminology interface abstract-class mixins
May 27 '09 at 10:59 p.m.
source share
7 answers

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(); // abstract (unimplemented method) def outline_width() = { return 1; } // default implementation } 

Subclass might look like

 class Rectangle extends Shape { int height = width = 5; def override area() = { return height * width; } // implements abstract method // no need to override outline_width(), but may do so if needed } 

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()); } } } 
+50
Mar 24 '13 at 22:56
source share

Generally:

Interface - This is a contract defining operations, but without any implementation. Some languages ​​(Java, C #) have built-in support for interfaces, while others have a description of an agreement, such as a pure virtual class in C ++.

An abstract class is a class that defines at least one operation without implementation. Abstract classes can also provide some parts of their implementation. Again, some languages ​​support marking classes as abstract, and this is implied in others. For example, in C ++, a class that defines a pure virtual method is abstract.

A mixin is a class that is designed to facilitate the implementation of certain functions in subclasses, but is not intended to be used on its own. For example, let's say that we have an interface for an object that processes requests

 interface RequestHandler { void handleRequest(Request request); } 

It might be useful to buffer requests, accumulating them until we have a given number, and then flush the buffer. We can implement buffering functionality with mixin without specifying flush behavior:

 abstract class BufferedRequestHandlerMixin implements RequestHandler { List<Request> buffer = new List<Request>(); void handleRequest(Request request) { buffer.add(request); if (buffer.size == BUFFER_FLUSH_SIZE) { flushBuffer(buffer); buffer.clear(); } } abstract void flushBuffer(List<Request> buffer); } 

Thus, it’s easy for us to write a query handler that writes requests to disk, calls a web service, etc., without overwriting each buffering function. These request handlers can simply extend BufferedRequestHandlerMixin and implement flushBuffer .

Another good mixin example is one of the many support classes in Spring, namely: HibernateDaoSupport .

+18
May 27 '09 at 23:05
source share

The Java reference and the given abstract class example for providing mixin is misleading. First of all, Java does not support "mixins" by default. In Java, the abstract class and Mixins get confused.

A mixin is a type that a class can implement in addition to its “primary type” to indicate that it provides some optional behavior. To speak Java, one example might be your business value object that implements Serializable.

Josh Bloch says: “Abstract classes cannot be used to define mixins - because a class cannot have more than one parent” (remember that Java only allows one “extends” candidate)

Look for languages ​​such as Scala and Ruby for the correct implementation of the concept of "mixin"

+6
Jul 29 '09 at 9:39
source share

In principle, an abstract class is an interface with some specific implementation. An interface is just a contract that has no implementation details.

You must use and abstract the class if you want to create common functionality for all objects that implement the abstract class. Storage using the principle of DRY (do not repeat yourself) OOP.

+3
May 27 '09 at 23:01
source share

An abstract class is a class in which not all of its members are implemented; they are left to implement the heirs. He forces his heirs to realize their abstract elements. Abstract classes cannot be created, and therefore their constructors should not be publicly available.]

Here is an example in C #:

  public abstract class Employee { protected Employee(){} public abstract double CalculateSalary(WorkingInfo workingInfo);//no implementation each type of employee should define its salary calculation method. } public class PartTimeEmployee:Employee { private double _workingRate; public Employee(double workingRate) { _workingRate=workingRate; } public override double CalculateSalary(WorkingInfo workingInfo) { return workingInfo.Hours*_workingRate; } 

}

An interface is a contract that must be implemented by a class. It simply declares the signature of the members of the implementing class and does not have the implementation itself. Usually we use interfaces to implement polymorphism and to decouple dependent classes.

Here is an example in C #:

 public interface IShape { int X{get;} int Y{get;} void Draw(); } public class Circle:IShape { public int X{get;set;} public int Y{get;set;} public void Draw() { //Draw a circle } } public class Rectangle:IShape { public int X{get;set;} public int Y{get;set;} public void Draw() { //Draw a rectangle } } 
+1
May 27 '09 at 23:33
source share

The meaning of “Mixin” is well defined by Joshua Bloch in his effective Java book. Excerpt from the same book:

"mixin is a type that a class can implement in addition to its" primary type "to declare that it provides some kind of optional behavior. For example, Comparable is a mixin interface that allows a class to declare that its instances are mutually ordered relative to others comparable objects: This interface is called mixin because it allows optional functionality to be "blended" with basic type functions.

+1
May 08 '14 at 4:13
source share

Since many of the guys explained the definitions and usage, I would like to highlight only important points

Interface:

  • To define a contract (preferably stateless - I don't mean variables)
  • To associate unrelated classes with " has a " capabilities.
  • Declare publicly available constant variables (immutable state)

Abstract class:

  • Share code between several closely related classes. He establishes the relationship " is a ".

  • The share of the general state among related classes (the state can be changed in specific classes)

I cover the difference with a small example.

Animal can be an abstract class. Cat and Dog , an extension of this abstract class establishes the relationship " is a ".

Cat is a Animal

Dog is a Animal.

Dog can implements the Bark interface. Then Dog has a ability to bark.

Cat can implement the Hunt interface. Then Cat has a Hunting ability.

A person who is not Animal can implement the Hunt interface. Then Man has a Hunting opportunity.

Man and animal (Cat / Dog) are not connected. But the Hunt interface can provide the same capabilities for unrelated objects.

Mixin:

  • If you need a mixture of both abstract class and interface . It is especially useful when you want to force a new contract in many unrelated classes, where some of them must redefine the new behavior, and some of them must adhere to the general implementation. Add a generic implementation in Mixin and let other classes override contract methods if necessary

If I want to declare an abstract class, I will follow one of these two approaches.

  • Move all abstract methods to interface , and my abstract class implements this interface.

     interface IHunt{ public void doHunting(); } abstract class Animal implements IHunt{ } class Cat extends Animal{ public void doHunting(){} } 

Related SE Question:

What is the difference between an interface and an abstract class?

+1
Jan 08 '16 at 10:33
source share



All Articles