CSC/ECE 517 Fall 2011/ch2 2c ds: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(81 intermediate revisions by 2 users not shown)
Line 1: Line 1:
=Mixins vs. Interfaces=
=Introduction=
=Introduction=
In object oriented programming languages, Mixins and Interfaces provide neat constructs to implement certain functionality and benefit from code re-usability. Understanding these constructs will benefit any programmer in designing any software with maximum polymorphic behavior and code re-usability.
With the advent of object oriented languages, the designers of the language had to come up with the decision of whether or not to include the concept of multiple inheritance. Languages like C++ and Perl allow multiple inheritance whereas the designers of languages like C# and Java decided not to because of the problems associated with multiple inheritance<ref>[http://www.artima.com/intv/gosling13.html Inspiration for Interface]</ref>.
While [http://en.wikipedia.org/wiki/Java_%28programming_language%29 Java] like languages implemented interfaces to allow for [http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming polymorphism],languages like [http://en.wikipedia.org/wiki/Ruby_%28programming_language%29 Ruby] opted not to implement multiple inheritance but to allow the code from one module be added into another class.
Though both interfaces and Mixins simulate multiple inheritance and avoid the common pathologies associated with it , they have their own set of compromises. The below article tries to provide clarity on how this is achieved in each and also provides other distinctive features of Mixins and interfaces.
===Interfaces===
===Interfaces===
In the Java programming language, an interface is a reference type, similar to a class that can contain only constants, method signatures, and nested types. There are no method bodies. Interfaces cannot be instantiated—they can only be implemented by classes or extended by other interfaces.
In an object-oriented programming languages such as Java, C#, an interface<ref>[http://download.oracle.com/javase/tutorial/ Interfaces] </ref> is a reference type, similar to a class that can contain only constants, method signatures, and nested types. There are no method bodies. Interfaces cannot be instantiated and they can only be implemented by classes or extended by other interfaces. All methods are public by default and any fields declared in an interface are by default static and final.  


Example:
Example:
Line 16: Line 27:
   }
   }


  public class Mall implements ParkingLot {
        boolean add(Car car, int slot) { //... Code to add a car into the parking lot... }
        boolean remove(Car car){ // do something }
        boolean findCar(Int number){ // do something }
        int freeSlotsCount(){ // do something }
        int occupiedSlots(){ // do something }
        int parkingType(){ // do something }
        int calculateParkingFee(int hours, int charge, int duration){ // do something }
        int findParkingSlot(){ // do something }
  }


Interfaces have another very important role in the Java programming language. Interfaces are not part of the class hierarchy, although they work in combination with classes. The Java programming language does not permit multiple inheritance (inheritance is discussed later in this lesson), but interfaces provide an alternative.
Interfaces play another important role in the object-oriented programming language. Interfaces are not part of the class hierarchy, although they work in combination with classes. Interfaces provide an alternative  for languages like Java that does not allow multiple inheritance .


In Java, a class can inherit from only one class but it can implement more than one interface. Therefore, objects can have multiple types: the type of their own class and the types of all the interfaces that they implement. This means that if a variable is declared to be the type of an interface, its value can reference any object that is instantiated from any class that implements the interface.
In Java, a class can inherit from only one class but it can implement more than one interface. Therefore, objects can have multiple types: the type of their own class and the types of all the interfaces that they implement. This means that if a variable is declared to be the type of an interface, its value can reference any object that is instantiated from any class that implements the interface.


==Mixins==
==Mixins==
A Mixin is a class that is mixed with a module or a set of modules i.e. the implementation of the modules and the class are intertwined and combined together. This gives us a neat and controlled way of adding new functionality to classes. Modules are similar to classes in that they hold a collection of methods, variables constants and other modules and class definitions.


The real usage of a Mixin is exploited when the code in the Mixin starts to interact with code in the class that uses it.
Modules provide a structure to collect classes, methods, and constants into a single, separately defined unit. They provide the simplest and an elegant way to adhere to the [http://en.wikipedia.org/wiki/Don't_repeat_yourself Don't repeat yourself] principle. This is useful so as to avoid clashes with existing classes, methods, and constants.
Modules provide a structure to collect Ruby classes, methods, and constants into a single, separately named and defined unit thereby. This is useful so that you can avoid clashes with existing classes, methods, and constants. They help the programmer adhere to the DRY (Don’t Repeat Yourself) principle and allows them to add the functionality of modules into your classes.


Modules are defined in Ruby using the module keyword.
Modules are defined in Ruby using the ''module'' keyword.


<source lang="ruby">
A Mixin is a class that is mixed with a module or a set of modules i.e. the implementation of the modules and the class are intertwined and combined together <ref>[http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html Mixins] </ref>.
module Test1 
 
  def method_A1
This gives us a neat and controlled way of adding new functionality to classes. Modules are similar to classes in that they hold a collection of methods, variables constants and other modules and class definitions. However, the real usage of a Mixin is exploited when the code in the Mixin starts to interact with code in the class that uses it.
  # … Some code … 
 
Below is an example for modules and Mixins:
 
The module ParkingSlot consists of the methods park and unpark
  <span style="color:#4682B4">
  module ParkingSlot
        def park
          #code to park the car
        end
        def unpark
          #code to unpark the car
        end
   end
   end
   def method_A2
</span>
  # … Some code…
The module ParkingMeter consists of the methods calculate and printreceipt
<span style="color:#F4A460">
   module ParkingMeter
        def calculate
          #code to calculate the parking fee
        end
        def printreceipt
          #code to print the receipt
        end
   end
   end
end
</span>
#Module A consists of the methods method_A1 and method_A2.
When a class ''includes'' a module via include Module Name, all the methods on that module become instance methods on the class.
<span style="color:#6B8E23">
  class Parking
      include ParkingSlot
      include ParkingMeter
      def printcardetails
          #code to print the details and type of car
      end
  end
</span>
The modules ParkingSlot and ParkingMeter are “included” in the Parking class. All the variables and the instance methods of the modules ParkingSlot and ParkingMeter are now said to be “mixed in” into the class. It is now possible for class instances to use these methods defined in the modules as and when required.


# Module B consists of the methods method_B1 and method_B2.
  p=Parking.new 
module Test2
  p.park            # -> Method park from module ParkingSlot
def method_B1
   p.unpark          # -> Method unpark from module ParkingSlot
   # … Some code … 
   p.calculate      # -> Method calculate from module ParkingMeter
   end
   p.printreceipt    # -> Method printreceipt from module ParkingMeter
   def method_B2
   p.printcardetails # -> Calls printCarDetails from class
   # … Some code…
 
  end
The class Parking inherits from both the modules and the module methods are now available in Parking. Hence, it is now possible to use the methods with an instance of the Parking class ''p''.
end
 
</source>
Hence, Mixins can be thought of taking different methods and variables defined in different modules making them available as instance methods in the class as well, thereby extending the class’ functionality. Effectively mixed in modules behave as [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)#Subclasses_and_superclasses superclass].
 
[[Image:ParkingLot.PNG | center]]


==Supported Languages==
==Supported Languages==
Line 87: Line 137:


=Multiple Inheritance=
=Multiple Inheritance=
Multiple Inheritance refers to a feature in some object oriented programming languages in which a class can inherit behaviors and behaviors from more than one superclass. This contrasts with single inheritance in which a class can inherit behavior from at most one superclass.  
[http://en.wikipedia.org/wiki/Multiple_inheritance Multiple Inheritance] refers to a feature in some [http://en.wikipedia.org/wiki/Object-oriented_programming object oriented programming] languages in which a class can inherit behaviors from more than one superclass. This contrasts with single inheritance in which a class can inherit behavior from at most one superclass.  
Though Multiple Inheritance provides its own advantages of improved modularity and ease of reuse of code in certain applications, it has its own set of disadvantages which sometimes outweigh the possible advantages.
Though Multiple Inheritance provides its own advantages of improved modularity and ease of reuse of code in certain applications, it has its own set of disadvantages which sometimes outweigh the possible advantages.


==Diamond Problem==
==Diamond Problem==
This section describes the well know “Diamond Problem” associated with multiple Inheritance and the succeeding sections describe how Mixins and interfaces can be used to overcome this problem.
This section describes the well know “Diamond Problem”<ref>[http://www.artima.com/designtechniques/interfaces2.html Diamond Problem] </ref> associated with multiple Inheritance and the succeeding sections describe how Mixins and interfaces can be used to overcome this problem.
The diamond problem is the ambiguity that can occur when a class inherits from two different classes that both descend from a common superclass. For example, consider a scenario where one decides to combine the Frog and Dinosaur species which both are inherited from the animal class. The talk() method in the Animal class is abstract and both Frog and Dinosaur needs to implement this method.
The diamond problem is the ambiguity that can occur when a class inherits from two different classes that both descend from a common superclass. For example, consider a scenario where one decides to combine the Frog and Dinosaur species which both are inherited from the Animal class. The talk() method in the Animal class is abstract and both Frog and Dinosaur needs to implement this method.


Lets say both Frog and Dinosaur implement the talk method like this:
Lets say both Frog and Dinosaur implement the talk method like this:
Line 100: Line 148:
     public class Frog extends Animal {
     public class Frog extends Animal {
           void talk() {
           void talk() {
               System.out.println(“I am Frog, I can crock “);
               System.out.println(“I am Frog, I can croak “);
           }  
           }  
   }
   }
Line 111: Line 159:
   }
   }


[[Image:Diamond_problem.PNG | center]]


When the Frogsaur is created, it inherits from both Frog and Dinosaur.  
When the Frogsaur is created, it inherits from both Frog and Dinosaur.  
Line 116: Line 165:


     public class Frogsaur extends Frog, Dinosaur {
     public class Frogsaur extends Frog, Dinosaur {
       // Note below syntax is used just for demonstration
       // Note below syntax is used just for demonstration. However java might throw compile time error.
     }
     }


The problem happens when someone tries to invoke talk() method on a Frogsaur object from the Animal reference.
The real problem occurs when someone tries to invoke talk() method on a Frogsaur object from the Animal reference.
      
      
     Animal animal = new Frogsaur();
     Animal species = new Frogsaur();
     animal.talk(); // which method to invoke ???
     species.talk(); // which method to invoke ???




Due to this ambiguity caused by the diamond problem, it isn’t clear whether the runtime system should invoke Frog’s talk() method or Dinosaur talk() method.  
Due to the ambiguity caused by the diamond problem, it isn’t clear whether the runtime system should invoke Frog’s talk() method or Dinosaur talk() method.
 


==Approaches==
==Approaches==
Different programming languages have addressed the diamond problem in different ways
Different programming languages have addressed the diamond problem in different ways.


In Java, interfaces solve all these ambiguities caused by the diamond problem. Through interfaces, Java allows multiple inheritance of interface but not of implementation. Implementation, which includes instance variables and method implementations, is always singly inherited. As a result, confusion will never arise in Java over which inherited instance variable or method implementation to use.
In Java, interfaces solve all these ambiguities caused by the diamond problem. Through interfaces, Java allows multiple inheritance of interface but not of implementation. Implementation, which includes instance variables and method implementations, is always singly inherited. As a result, confusion will never arise in Java over which inherited instance variable or method implementation to use.


Ruby does not support multiple inheritance. Mixin provide a way which eliminates the need for multiple inheritance. Ruby has modules which are just like abstract classes in Java. Modules can have different methods implemented in them. They cannot be instantiated like abstract classes. They cannot inherit from other modules or classes. Ruby classes can inherit from only one superclass but can have unlimited number of modules in them to exploit the usage of predefined implementations in these modules. This provides functionality similar to multiple inheritance avoiding any ambiguities.
Ruby does not support multiple inheritance. Mixin provide a way which eliminates the need for multiple inheritance. Ruby has modules which are just like abstract classes<ref>[http://download.oracle.com/javase/tutorial/java/IandI/abstract.html Abstract Classes]</ref> in Java. Modules can have different methods implemented in them. They cannot be instantiated like abstract classes. They cannot inherit from other modules or classes. Ruby classes can inherit from only one superclass but can have unlimited number of modules in them to exploit the usage of predefined implementations in these modules. This provides functionality similar to multiple inheritance avoiding any ambiguities.
 
The below code demonstrates two modules Frog and Dinosaur, each of which contain the talk method defined in them. The Frogsaur class ''includes'' these two methods and defines its own talk method. This example was chosen to exhibit on how Ruby resolves method calls at run time.


The below code in Ruby demonstrates two modules Frog and Dinosaur, each of which contain the talk method defined in them. The Frogsaur class ''includes'' these two methods and defines its own talk method. This example was chosen to exhibit on how Ruby resolves method calls at run time.


   module Frog
   module Frog
Line 158: Line 205:
   end
   end


   fs = Frogsaur.new
   fs = Frogsaur.new  
   fs.talk
   fs.talk         # -> Which talk method to call ??


When the method talk is called on the Frogsaur object, Ruby makes sure that the latest method defined in the hierarchy is chosen. Here in this example, the talk method in the Frogsaur class is defined the latest and hence “I can roar like a dinosaur and croak like a frog” is printed. If there was no method defined in the class, method from the Dinosaur is printed since it is next in the hierarchy specified by the include statements.
When the method talk is called on the Frogsaur object, Ruby makes sure that the latest method defined in the hierarchy is chosen. Here in this example, the talk method in the Frogsaur class is defined the latest and hence “I can roar like a dinosaur and croak like a frog” is printed. If there was no method defined in the class, method from the Dinosaur is printed since it is next in the hierarchy specified by the include statements.


[[Media:Example.ogg]]=Comparison between Mixins and Interfaces=
=Comparison between Mixins and Interfaces=


These is a general comparision:  
This is a general comparision:  


{| class="wikitable"
{| class="wikitable"
|-
|-
! Features
! Mixins
! Mixins
! Interfaces
! Interfaces
|-
|-
| Maintainability
| In Ruby, modules have the implementation of the methods. So all the classes which include the modules gets the same Implementation because  classes create a reference to these modules.
| In Ruby, modules have the implementation of the methods. So all the classes which include the modules gets the same Implementation because  classes create a reference to these modules.
|In Java, all classes which implement the interfaces should provide implementation for each of the methods declared in the interface. This might duplicate the code if the 2 or more classes have similar functionality.
|In Java, all classes which implement the interfaces should provide implementation for each of the methods declared in the interface. This might duplicate the code if the two or more classes have similar functionality.
|-
|-
| Overall size of the code
| The size of the code is relatively smaller because the classes automatically get access to methods defined in the modules. Modules server as a central repository
| Relatively smaller because the classes automatically get access to methods defined in the modules. Modules server as a central repository
| The size is relatively larger because a class implementing more than one interfaces has to provide implementation.
| Relatively larger because a class implementing more than one interfaces has to provide implementation.
|-
|-
| Readability
| Having more modules in the classes can make code less readable. Ideally mixins are suitable for small teams having few modules.  
| Having more modules in the classes can make code less readable. Ideally mixins are suitable for small teams having few modules.  
| The code is more readable here as the implementation is provided to each method and can be found in place
| The code is more readable here as the implementation is provided to each method and can be found in place
|-
|-
| Namespace
| In Ruby, a method inside a module can have Module name as qualifier. Hence it’s possible for a class to have inherit two or more modules which have same names.
| In Ruby, a method inside a module can have Module name as qualifier. Hence it’s possible for a class to have inherit two or more modules which have same names.
| In Java, the class itself has to provide the implementation of the methods. Inheriting methods of same names from different interfaces will signal an error message.
| In Java, the class itself has to provide the implementation of the methods. Inheriting methods of same names from different interfaces will signal an error message.
|-
|-
| Inheritance
| Modules cannot be inherited and cannot form is-a hierarchy
| Modules cannot be inherited and cannot form is-a hierarchy
| Interfaces can extend another interface and hence can form is-a hierarchy
| Interfaces can extend another interface and hence can form is-a hierarchy
Line 196: Line 237:
==Drawbacks of Mixins and Interfaces==
==Drawbacks of Mixins and Interfaces==


The drawbacks of the technique of Mixins are very much debated. Though Mixins provide us with an easy way to write flexible and decoupled code and also help us solve the diamond problem, they pose their own problems. In large programs there could be large number of modules and each module could have loads of methods each performing a certain task, to trace the origin of the methods and to keep in mind the hierarchy is practically impossible. Another issue associated with Mixins pose is silent method overriding.
The drawbacks of the technique of Mixins are very much debated. Though Mixins provide us with an easy way to write flexible and decoupled code and also help us solve the diamond problem, they pose their own problems. In large programs there could be large number of modules and each module could have loads of methods each performing a certain task.To trace the origin of the methods and to keep in mind the hierarchy is practically impossible. Another issue associated with Mixins pose is silent method overriding. Silent method overriding occurs when different modules are included in a class and each module have a method with the same definition. In such a case, the method which gets executed depends upon the way it is included in the class and this is done without any sort of message to the user (silently). In large scale applications this could certainly be an issue considering the number of modules that would be mixed in and it would be difficult to keep track of the hierarchy in which the modules were included.
 
Although Java provides polymorphic behavior with the use of interfaces, they sometimes tend to be very slow. The implementation of interfaces are also limited to public methods and constants with no implementation.
Although Java provides polymorphic behavior with the use of interfaces, they sometimes tend to be very slow. The implementation of interfaces are also limited to public methods and constants with no implementation.


Line 203: Line 245:


=References=
=References=
<references/>


=Useful links=
=See Also=
1. http://ruby.about.com/od/beginningruby/a/mixin.html<br>
2. http://juixe.com/techknow/index.php/2006/06/15/mixins-in-ruby/ <br>
3. https://www.re-motion.org/blogs/team/2008/02/20/introducing-mixins-finally/ <br>
4. https://www.cs.washington.edu/education/courses/cse413/11sp/lectures/ruby_interfaces-etc.pdf <br>
5. http://pg-server.csc.ncsu.edu/mediawiki/index.php?title=CSC/ECE_517_Fall_2010/ch3_3b_sv&printable=yes <br>
6. http://csis.pace.edu/~bergin/patterns/multipleinheritance.html

Latest revision as of 23:48, 30 September 2011

Mixins vs. Interfaces

Introduction

In object oriented programming languages, Mixins and Interfaces provide neat constructs to implement certain functionality and benefit from code re-usability. Understanding these constructs will benefit any programmer in designing any software with maximum polymorphic behavior and code re-usability.

With the advent of object oriented languages, the designers of the language had to come up with the decision of whether or not to include the concept of multiple inheritance. Languages like C++ and Perl allow multiple inheritance whereas the designers of languages like C# and Java decided not to because of the problems associated with multiple inheritance<ref>Inspiration for Interface</ref>.

While Java like languages implemented interfaces to allow for polymorphism,languages like Ruby opted not to implement multiple inheritance but to allow the code from one module be added into another class.

Though both interfaces and Mixins simulate multiple inheritance and avoid the common pathologies associated with it , they have their own set of compromises. The below article tries to provide clarity on how this is achieved in each and also provides other distinctive features of Mixins and interfaces.

Interfaces

In an object-oriented programming languages such as Java, C#, an interface<ref>Interfaces </ref> is a reference type, similar to a class that can contain only constants, method signatures, and nested types. There are no method bodies. Interfaces cannot be instantiated and they can only be implemented by classes or extended by other interfaces. All methods are public by default and any fields declared in an interface are by default static and final.

Example:

 public interface ParkingLot {
       boolean add(Car car, int slot);
       boolean remove(Car car);
       boolean findCar(Int number);
       int freeSlotsCount();
       int occupiedSlots();
       int parkingType();
       int calculateParkingFee(int hours, int charge, int duration);
       int findParkingSlot();
 }
 public class Mall implements ParkingLot {
       boolean add(Car car, int slot) { //... Code to add a car into the parking lot... }
       boolean remove(Car car){ // do something }
       boolean findCar(Int number){ // do something }
       int freeSlotsCount(){ // do something }
       int occupiedSlots(){ // do something }
       int parkingType(){ // do something }
       int calculateParkingFee(int hours, int charge, int duration){ // do something }
       int findParkingSlot(){ // do something }
 }

Interfaces play another important role in the object-oriented programming language. Interfaces are not part of the class hierarchy, although they work in combination with classes. Interfaces provide an alternative for languages like Java that does not allow multiple inheritance .

In Java, a class can inherit from only one class but it can implement more than one interface. Therefore, objects can have multiple types: the type of their own class and the types of all the interfaces that they implement. This means that if a variable is declared to be the type of an interface, its value can reference any object that is instantiated from any class that implements the interface.

Mixins

Modules provide a structure to collect classes, methods, and constants into a single, separately defined unit. They provide the simplest and an elegant way to adhere to the Don't repeat yourself principle. This is useful so as to avoid clashes with existing classes, methods, and constants.

Modules are defined in Ruby using the module keyword.

A Mixin is a class that is mixed with a module or a set of modules i.e. the implementation of the modules and the class are intertwined and combined together <ref>Mixins </ref>.

This gives us a neat and controlled way of adding new functionality to classes. Modules are similar to classes in that they hold a collection of methods, variables constants and other modules and class definitions. However, the real usage of a Mixin is exploited when the code in the Mixin starts to interact with code in the class that uses it.

Below is an example for modules and Mixins:

The module ParkingSlot consists of the methods park and unpark

 
 module ParkingSlot
       def park
          #code to park the car
       end
       def unpark
          #code to unpark the car
       end
 end

The module ParkingMeter consists of the methods calculate and printreceipt


 module ParkingMeter
       def calculate
          #code to calculate the parking fee
       end
       def printreceipt
          #code to print the receipt
       end
 end

When a class includes a module via include Module Name, all the methods on that module become instance methods on the class.


 class Parking
      include ParkingSlot
      include ParkingMeter
      def printcardetails
          #code to print the details and type of car
      end
 end

The modules ParkingSlot and ParkingMeter are “included” in the Parking class. All the variables and the instance methods of the modules ParkingSlot and ParkingMeter are now said to be “mixed in” into the class. It is now possible for class instances to use these methods defined in the modules as and when required.

 p=Parking.new   
 p.park            # -> Method park from module ParkingSlot
 p.unpark          # -> Method unpark from module ParkingSlot
 p.calculate       # -> Method calculate from module ParkingMeter
 p.printreceipt    # -> Method printreceipt from module ParkingMeter
 p.printcardetails # -> Calls printCarDetails from class

The class Parking inherits from both the modules and the module methods are now available in Parking. Hence, it is now possible to use the methods with an instance of the Parking class p.

Hence, Mixins can be thought of taking different methods and variables defined in different modules making them available as instance methods in the class as well, thereby extending the class’ functionality. Effectively mixed in modules behave as superclass.

Supported Languages

The following table shows support for Mixins and Interfaces by most commonly used languages.

Languages Mixins Interfaces
Ruby Yes No
Java No Yes
Python Yes No
Smalltalk Yes No
Perl Yes No
C# No Yes

Multiple Inheritance

Multiple Inheritance refers to a feature in some object oriented programming languages in which a class can inherit behaviors from more than one superclass. This contrasts with single inheritance in which a class can inherit behavior from at most one superclass. Though Multiple Inheritance provides its own advantages of improved modularity and ease of reuse of code in certain applications, it has its own set of disadvantages which sometimes outweigh the possible advantages.

Diamond Problem

This section describes the well know “Diamond Problem”<ref>Diamond Problem </ref> associated with multiple Inheritance and the succeeding sections describe how Mixins and interfaces can be used to overcome this problem. The diamond problem is the ambiguity that can occur when a class inherits from two different classes that both descend from a common superclass. For example, consider a scenario where one decides to combine the Frog and Dinosaur species which both are inherited from the Animal class. The talk() method in the Animal class is abstract and both Frog and Dinosaur needs to implement this method.

Lets say both Frog and Dinosaur implement the talk method like this:

   public class Frog extends Animal {
         void talk() {
              System.out.println(“I am Frog, I can croak “);
         } 
  }

and,

   public class Dinosaur extends Animal {
         void talk() {
              System.out.println(“I am Dinosaur, I can roar “);
         } 
  }

When the Frogsaur is created, it inherits from both Frog and Dinosaur.


   public class Frogsaur extends Frog, Dinosaur {
      // Note below syntax is used just for demonstration. However java might throw compile time error.
   }

The real problem occurs when someone tries to invoke talk() method on a Frogsaur object from the Animal reference.

   Animal species = new Frogsaur();
   species.talk(); // which method to invoke ???


Due to the ambiguity caused by the diamond problem, it isn’t clear whether the runtime system should invoke Frog’s talk() method or Dinosaur talk() method.

Approaches

Different programming languages have addressed the diamond problem in different ways.

In Java, interfaces solve all these ambiguities caused by the diamond problem. Through interfaces, Java allows multiple inheritance of interface but not of implementation. Implementation, which includes instance variables and method implementations, is always singly inherited. As a result, confusion will never arise in Java over which inherited instance variable or method implementation to use.

Ruby does not support multiple inheritance. Mixin provide a way which eliminates the need for multiple inheritance. Ruby has modules which are just like abstract classes<ref>Abstract Classes</ref> in Java. Modules can have different methods implemented in them. They cannot be instantiated like abstract classes. They cannot inherit from other modules or classes. Ruby classes can inherit from only one superclass but can have unlimited number of modules in them to exploit the usage of predefined implementations in these modules. This provides functionality similar to multiple inheritance avoiding any ambiguities.

The below code in Ruby demonstrates two modules Frog and Dinosaur, each of which contain the talk method defined in them. The Frogsaur class includes these two methods and defines its own talk method. This example was chosen to exhibit on how Ruby resolves method calls at run time.

 module Frog
     def talk
         puts "I can croak"
     end
 end
 module Dinosaur
     def talk
         puts "I can roar"
     end
 end
 class Frogsaur
     include Frog 
     include Dinosaur
        def talk
            puts "I can roar like a dinosaur and croak like a frog"
        end
 end
 fs = Frogsaur.new 
 fs.talk         # -> Which talk method to call ??

When the method talk is called on the Frogsaur object, Ruby makes sure that the latest method defined in the hierarchy is chosen. Here in this example, the talk method in the Frogsaur class is defined the latest and hence “I can roar like a dinosaur and croak like a frog” is printed. If there was no method defined in the class, method from the Dinosaur is printed since it is next in the hierarchy specified by the include statements.

Comparison between Mixins and Interfaces

This is a general comparision:

Mixins Interfaces
In Ruby, modules have the implementation of the methods. So all the classes which include the modules gets the same Implementation because classes create a reference to these modules. In Java, all classes which implement the interfaces should provide implementation for each of the methods declared in the interface. This might duplicate the code if the two or more classes have similar functionality.
The size of the code is relatively smaller because the classes automatically get access to methods defined in the modules. Modules server as a central repository The size is relatively larger because a class implementing more than one interfaces has to provide implementation.
Having more modules in the classes can make code less readable. Ideally mixins are suitable for small teams having few modules. The code is more readable here as the implementation is provided to each method and can be found in place
In Ruby, a method inside a module can have Module name as qualifier. Hence it’s possible for a class to have inherit two or more modules which have same names. In Java, the class itself has to provide the implementation of the methods. Inheriting methods of same names from different interfaces will signal an error message.
Modules cannot be inherited and cannot form is-a hierarchy Interfaces can extend another interface and hence can form is-a hierarchy

Drawbacks of Mixins and Interfaces

The drawbacks of the technique of Mixins are very much debated. Though Mixins provide us with an easy way to write flexible and decoupled code and also help us solve the diamond problem, they pose their own problems. In large programs there could be large number of modules and each module could have loads of methods each performing a certain task.To trace the origin of the methods and to keep in mind the hierarchy is practically impossible. Another issue associated with Mixins pose is silent method overriding. Silent method overriding occurs when different modules are included in a class and each module have a method with the same definition. In such a case, the method which gets executed depends upon the way it is included in the class and this is done without any sort of message to the user (silently). In large scale applications this could certainly be an issue considering the number of modules that would be mixed in and it would be difficult to keep track of the hierarchy in which the modules were included.

Although Java provides polymorphic behavior with the use of interfaces, they sometimes tend to be very slow. The implementation of interfaces are also limited to public methods and constants with no implementation.

Conclusion

Although mixins have certain advantages over interfaces, they possess their own share of disadvantages. Mixins are generally used in small frameworks and interfaces , more than solving the problem of multiple inheritance provide polymorphism feature which makes object-oriented code more flexible and easy to modify and maintain.

References

<references/>

See Also

1. http://ruby.about.com/od/beginningruby/a/mixin.html
2. http://juixe.com/techknow/index.php/2006/06/15/mixins-in-ruby/
3. https://www.re-motion.org/blogs/team/2008/02/20/introducing-mixins-finally/
4. https://www.cs.washington.edu/education/courses/cse413/11sp/lectures/ruby_interfaces-etc.pdf
5. http://pg-server.csc.ncsu.edu/mediawiki/index.php?title=CSC/ECE_517_Fall_2010/ch3_3b_sv&printable=yes
6. http://csis.pace.edu/~bergin/patterns/multipleinheritance.html