CSC/ECE 517 Fall 2011/ch2 2c ds
Introduction
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.
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(); }
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.
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
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 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.
module Test1
def method_A1
# … Some code …
end
def method_A2
# … Some code…
end
end
#Module A consists of the methods method_A1 and method_A2.
# Module B consists of the methods method_B1 and method_B2.
module Test2
def method_B1
# … Some code …
end
def method_B2
# … Some code…
end
end
Supported Languages
Multiple Inheritance
Diamond Problem
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 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.
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
Comparison between 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. 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.