CSC/ECE 517 Fall 2012/ch1b 1w37 ss: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(25 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Modules and Mixins   
Modules and Mixins   
 


==  Regular Expressions ==
==  Regular Expressions ==
Line 9: Line 9:


   
   
* [http://en.wikipedia.org/wiki/Regular_expression/ Regular expressions] are extremely powerful.Ruby was built as a better Perl hence it supports regular expressions.  
* [http://en.wikipedia.org/wiki/Regular_expression Regular expressions] are extremely powerful.[http://en.wikipedia.org/wiki/Ruby_(programming_language) Ruby]was built as a better [http://en.wikipedia.org/wiki/Perl Perl] hence it supports regular expressions.  
* Regular expression is sort of a string used to match to other strings.In ruby regular expressions are written in the format /pattern/modifiers where pattern is the regular expression and modifiers are the series of characters specifying the various options.  
* [http://en.wikipedia.org/wiki/Regular_expression Regular expression] is sort of a string used to match to other strings.In ruby regular expressions are written in the format /pattern/modifiers where pattern is the regular expression and modifiers are the series of characters specifying the various options.  
* To understand the power of regular expressions here is an example.
* To understand the power of regular expressions here is an example.
   
   
Line 92: Line 92:
options: i case insensitive m make dot match newlines x ignore whitespace in regex  
options: i case insensitive m make dot match newlines x ignore whitespace in regex  
o perform #{...} substitutions only once
o perform #{...} substitutions only once
</<pre>>
</pre>
More Examples  
More Examples  


Line 99: Line 99:
/([Rr])uby&\1ails/ Match ruby&rails or Ruby&Rails
/([Rr])uby&\1ails/ Match ruby&rails or Ruby&Rails
/(['"])(?:(?!\1).)*\1/ Single or double-quoted string. \1 matches whatever the 1st group matched . \2 matches whatever the 2nd group matched, etc.
/(['"])(?:(?!\1).)*\1/ Single or double-quoted string. \1 matches whatever the 1st group matched . \2 matches whatever the 2nd group matched, etc.
<pre/>
</pre>
Example Description
Example Description
<pre>
<pre>
Line 110: Line 110:
/Ruby(?=!)/ Match "Ruby", if followed by an exclamation point
/Ruby(?=!)/ Match "Ruby", if followed by an exclamation point
/Ruby(?!!)/ Match "Ruby", if not followed by an exclamation point
/Ruby(?!!)/ Match "Ruby", if not followed by an exclamation point
<pre/>
</pre>
Example  
Example  
<pre>
<pre>
Line 124: Line 124:
This will produce following result:
This will produce following result:
Line1 starts with Cats
Line1 starts with Cats
<pre/>
</pre>
Example
Example
<pre>
<pre>
Line 148: Line 148:




* Ruby Modules are similar to classes in that they hold a collection of methods,constants and other module and class definitions.  
* Ruby [http://en.wikipedia.org/wiki/Mixin Modules] are similar to classes in that they hold a collection of methods,constants and other module and class definitions.  
* Modules definition is similar to classes just that we use the keyword module instead of the class keyword.
* Modules definition is similar to classes just that we use the keyword module instead of the class keyword.


====  How Modules differ from classes? ====
====  How Modules differ from classes? ====
   
   


Unlike classes, objects cannot be created based on modules nor can it be sub classed.However, it can be specified that the functionality of one module should be added to another class, or a specific object.
Unlike [http://en.wikipedia.org/wiki/Object-oriented_programming classes], [http://en.wikipedia.org/wiki/Object-oriented_programming objects] cannot be created based on modules nor can it be sub classed.However, it can be specified that the functionality of one module should be added to another class, or a specific object.
 


==== Uses of modules ====
==== Uses of modules ====
Line 162: Line 160:


Modules serve two purpose:
Modules serve two purpose:
1.They act as namespace in C++, letting definition of methods whose names will not clash with those defined elsewhere.
1.They act as namespace in [http://en.wikipedia.org/wiki/C%2B%2B C++], letting definition of methods whose names will not clash with those defined elsewhere.
2.Modules allow to share functionality between classes.
2.Modules allow to share functionality between classes.


Line 169: Line 167:
   
   


* Here's an example taken from class notes Class notes of CSC517, NCSU to illustrate modules.
* Here's an example taken from class notes [http://courses.ncsu.edu/csc517//common/lectures/notes/lec6.pdf Class notes of CSC517, NCSU] to illustrate modules.
* Suppose there is a graphics library that contains classes for Windows(windows.rb) and Border(border.rb).Window.rb and border.rb have a top method,which gives the position of the top of the Windows and top of the border respectively.
* Suppose there is a graphics library that contains classes for Windows(windows.rb) and Border(border.rb).Window.rb and border.rb have a top method,which gives the position of the top of the Windows and top of the border respectively.
* To layout windows with borders,both windows.rb and border.rb have to be loaded into the program.However, as the top method is in both classes one of them will be overridden.
* To layout windows with borders,both windows.rb and border.rb have to be loaded into the program.However, as the top method is in both classes one of them will be overridden.
Line 192: Line 190:
end
end


When a program needs to use these modules, it can simply load the two files using the Ruby require statement, and reference the qualified names.
When a program needs to use these modules, it can simply load the two files using the Ruby [http://ruby.about.com/od/rubyfeatures/a/require.htm require] statement, and reference the qualified names.


   
   
Line 207: Line 205:




* The most interesting fact about the use of modules is to define mixins. When a module is included within a class,all its functionality becomes available to the class.
* The most interesting fact about the use of modules is to define [http://en.wikipedia.org/wiki/Mixin mixins]. When a module is included within a class,all its functionality becomes available to the class.
* Modules can contain class methods and instance methods.
* Modules can contain [http://en.wikipedia.org/wiki/Method_(computer_programming)#Class_methods class methods] and [http://www.daniweb.com/software-development/java/threads/303430/what-is-instance-method instance methods].


==== How [http://en.wikipedia.org/wiki/Mixin mixins]is different from  #include and multiple inheritance? ====


==== How mixins is different from  #include and multiple inheritance? ====


 
* Let's see how [http://en.wikipedia.org/wiki/Mixin mixins]is contrasting to #include and multiple inheritance in other languages.#include files define methods that can be called but not applied to objects.
* Let's see how mixins is contrasting to #include and multiple inheritance in other languages.#include files define methods that can be called but not applied to objects.
* By using [http://en.wikipedia.org/wiki/Mixin mixins]the same methods can be added to any number of different classes;regardless of hierarchy.
* By using mixins the same methods can be added to any number of different classes;regardless of hierarchy.
* [http://en.wikipedia.org/wiki/Mixin mixins]corresponds to the usage of interfaces in Java.
* Mixins corresponds to the usage of interfaces in Java.




Line 222: Line 219:
   
   
<pre>
<pre>
Consider the following example taken from class notes Class notes of CSC517, NCSU to illustrate mixins.
Consider the following example taken from class notes [http://courses.ncsu.edu/csc517//common/lectures/notes/lec6.pdf Class notes of CSC517, NCSU] to illustrate mixins.


   
   
Line 286: Line 283:




==== Namespace in C++ (similar to modules) ====
==== Namespace in [http://en.wikipedia.org/wiki/C%2B%2B C++] (similar to modules) ====




Line 292: Line 289:
=====  Definition =====
=====  Definition =====
   
   
* In general, a namespace is a container for a set of identifiers (names), and allows the disambiguation of homonym identifiers residing in different namespaces.
* In general, a [http://en.wikipedia.org/wiki/Namespace namespace] is a container for a set of identifiers (names), and allows the disambiguation of homonym identifiers residing in different namespaces.
* Namespaces usually group names based on their functionality.  
* [http://en.wikipedia.org/wiki/Namespace Namespace] usually group names based on their functionality.  




Line 299: Line 296:


To use C++ namespaces, there are two steps involved:
To use C++ namespaces, there are two steps involved:
* To uniquely identify a namespace with the keyword namespace.
* To uniquely identify a [http://en.wikipedia.org/wiki/Namespace namespace]with the keyword [http://en.wikipedia.org/wiki/Namespace namespace].
* To access the elements of an identified namespace by applying the using keyword.
* To access the elements of an identified [http://en.wikipedia.org/wiki/Namespace namespace] by applying the using keyword.


   
   
Line 311: Line 308:
       long q
       long q
}
}
* p and q are normal variables but integrated within the NewOne namespace.   
* p and q are normal variables but integrated within the NewOne [http://en.wikipedia.org/wiki/Namespace namespace].   
* In order to access this variables from the outside the namespace, we have to use the scope operator ::.  
* In order to access this variables from the outside the [http://en.wikipedia.org/wiki/Namespace namespace], we have to use the scope operator ::.  
* From previous example:
* From previous example:


Line 318: Line 315:
NewOne::q;
NewOne::q;


A namespace definition can be nested within another namespace definition.  Every namespace definition must appear either at file scope or immediately within another namespace definition.  For example:
A namespace definition can be nested within another [http://en.wikipedia.org/wiki/Namespace namespace]definition.  Every namespace definition must appear either at file scope or immediately within another namespace definition.  For example:


// a namespace with using directive
// a namespace with using directive
Line 360: Line 357:
===== Definition =====
===== Definition =====
   
   
You can derive a class from any number of base classes. Deriving a class from more than one direct base class is called multiple inheritance.
You can derive a class from any number of base classes. Deriving a class from more than one direct base class is called [http://en.wikipedia.org/wiki/Multiple_inheritance multiple inheritance].
 


===== Example =====
===== Example =====
<pre>
<pre>
Line 373: Line 370:
The following inheritance graph describes the inheritance relationships of the above example. An arrow points to the direct base class of the class at the tail of the arrow:
The following inheritance graph describes the inheritance relationships of the above example. An arrow points to the direct base class of the class at the tail of the arrow:
   
   
The order of derivation is relevant only to determine the order of default initialization by constructors and cleanup by destructors.
 
The order of derivation is relevant only to determine the order of default [http://en.wikipedia.org/wiki/Initialization_(programming) initialization] by [http://en.wikipedia.org/wiki/Constructor constructors] and cleanup by [http://en.wikipedia.org/wiki/Destructor_(computer_programming) destructors].
A direct base class cannot appear in the base list of a derived class more than once:
A direct base class cannot appear in the base list of a derived class more than once:
class B1 { /* ... */ };                  // direct base class
class B1 { /* ... */ };                  // direct base class
Line 391: Line 390:
You can also avoid this ambiguity by using the base specifier virtual to declare a base class, as described in Derivation (C++ only).
You can also avoid this ambiguity by using the base specifier virtual to declare a base class, as described in Derivation (C++ only).
</pre>
</pre>
==== Interface (Java) (similar to mixins) ====
==== Interface (Java) (similar to mixins) ====
   
   
Line 396: Line 396:
===== Definition =====
===== Definition =====
   
   
* A Java interface defines a set of methods but does not implement them.  
* A [http://en.wikipedia.org/wiki/Java_(programming_language) Java] interface defines a set of methods but does not implement them.  
* A class that implements the interface agrees to implement all of the methods defined in the interface, thereby agreeing to certain behavior, thereby implementing multiple inheritance.
* A class that implements the [http://en.wikipedia.org/wiki/Interface_(Java) interface] agrees to implement all of the methods defined in the interface, thereby agreeing to certain behavior, thereby implementing [http://en.wikipedia.org/wiki/Multiple_inheritance multiple inheritance].


===== Properties of Interface: =====
===== Properties of Interface: =====


* An interface is implicitly abstract. You do not need to use the abstract keyword when declaring an interface.
* An [http://www.codeproject.com/Articles/10553/Using-Interfaces-in-C interface] is implicitly abstract. You do not need to use the abstract keyword when declaring an interface.
* Each method in an interface is also implicitly abstract, so the abstract keyword is not needed.
* Each method in an interface is also implicitly abstract, so the abstract keyword is not needed.
* Methods in an interface are implicitly public.
* Methods in an interface are implicitly public.
Line 407: Line 407:
===== Example =====
===== Example =====
<pre>
<pre>
* When a class implements an interface, you can think of the class as signing a contract, agreeing to perform the specific behaviors of the interface.  
* When a class implements an [http://en.wikipedia.org/wiki/Interface_(Java) interface], you can think of the class as signing a contract, agreeing to perform the specific behaviors of the interface.  
* If a class does not perform all the behaviors of the interface, the class must declare itself as abstract.
* If a class does not perform all the behaviors of the [http://en.wikipedia.org/wiki/Interface_(Java) interface], the class must declare itself as abstract.
/* File name : Animal.java */
/* File name : Animal.java */
interface Animal {
interface Animal {
Line 416: Line 416:
}
}


* Aclass uses the implements keyword to implement an interface. The implements keyword appears in the class declaration following the extends portion of the declaration.
* A class uses the [http://www.roseindia.net/help/java/i/implement-keyword.shtml implements] keyword to implement an [http://en.wikipedia.org/wiki/Interface_(Java) interface]. The implements keyword appears in the class declaration following the extends portion of the declaration.
/* File name : MammalInt.java */
/* File name : MammalInt.java */
public class MammalInt implements Animal{
public class MammalInt implements Animal{
Line 442: Line 442:
Mammal travels
Mammal travels
</pre>
</pre>


== Comparable ==
== Comparable ==
Line 451: Line 450:




* The comparable mixin is used by classes whose objects may be ordered.
* The [http://www.ruby-doc.org/core-1.9.3/Comparable.html comparable] mixin is used by classes whose objects may be ordered.
* The class must define the <=> operator, which compares the receiver against another object,returning -1,0 or +1 depending on whether the receiver is less than,equal to ,or greater than the other object.  
* The class must define the <=> [http://en.wikipedia.org/wiki/Operator operator], which compares the receiver against another object,returning -1,0 or +1 depending on whether the receiver is less than,equal to ,or greater than the other object.  
* If the other object is not comparable then is should just return nil.Comparable uses <=> to implement the comparison operators(<,<=,==,=>,and >) and the method between?.
* If the other object is not comparable then is should just return nil.[http://www.ruby-doc.org/core-1.9.3/Comparable.html comparable]uses <=> to implement the comparison operators(<,<=,==,=>,and >) and the method between?.




Line 459: Line 458:


<pre>
<pre>
Here is an example taken from class notes Class notes of CSC517, NCSU to illustrate comparable mixin.
Here is an example taken from class notes [http://courses.ncsu.edu/csc517//common/lectures/notes/lec6.pdf Class notes of CSC517, NCSU] to illustrate [http://www.ruby-doc.org/core-1.9.3/Comparable.html comparable]mixin.


class Line  
class Line  
Line 509: Line 508:




Enumerable is a standard mixin which can be used to put into other classes.It has a method called inject that can be applied to adjacent elements of a set.
[http://ruby-doc.org/core-1.9.3/Enumerable.html Enumerable] is a standard mixin which can be used to put into other classes.It has a method called inject that can be applied to adjacent elements of a set.




Line 521: Line 520:
</pre>
</pre>
* As seen in the above example inject is used on all elements of the set to add them and display the result.
* As seen in the above example inject is used on all elements of the set to add them and display the result.
* To understand the working of Enumerable mixin in class,consider the following example taken from class notes Class notes of CSC517, NCSU. The class VowelFinder returns successive vowels in a string using the Enumerable mixin method.
* To understand the working of [http://ruby-doc.org/core-1.9.3/Enumerable.html Enumerable]mixin in class,consider the following example taken from class notes [http://courses.ncsu.edu/csc517//common/lectures/notes/lec6.pdf Class notes of CSC517, NCSU]. The class VowelFinder returns successive vowels in a string using the [http://ruby-doc.org/core-1.9.3/Enumerable.html Enumerable]mixin method.
<pre>
<pre>


Line 544: Line 543:




* Multiple Inheritance has several disadvantages that can lead to ambiguous code behavior either during compile time or run time.
* [http://en.wikipedia.org/wiki/Multiple_inheritance Multiple Inheritance] has several disadvantages that can lead to ambiguous code behavior either during compile time or run time.
* Ruby does not support direct Multiple Inheritance. But, Multiple Inheritance can be achieved in Ruby through Modules. Modules simulate multiple inheritance in Ruby.
* Ruby does not support direct[http://en.wikipedia.org/wiki/Multiple_inheritance Multiple Inheritance]. But, Multiple Inheritance can be achieved in Ruby through Modules. Modules simulate multiple inheritance in Ruby.
* Given below is the Taggable-string example taken from the Class notes of CSC517, NCSU. Suppose we want to add tags to Strings, we can define a Taggable module and include it into the class.
* Given below is the Taggable-string example taken from the [http://courses.ncsu.edu/csc517//common/lectures/notes/lec6.pdf Class notes of CSC517, NCSU]. Suppose we want to add tags to Strings, we can define a Taggable module and include it into the class.




Line 622: Line 621:




Although multiple inheritance has its disadvantages, there are a couple of good reasons for using multiple inheritance. Generally, multiple inheritance is used in one of the following ways:
Although [http://en.wikipedia.org/wiki/Multiple_inheritance multiple inheritance] has its disadvantages, there are a couple of good reasons for using multiple inheritance. Generally, multiple inheritance is used in one of the following ways:


'''1. Multiple Independant Protocols'''
'''1. Multiple Independant Protocols'''
* This is used when a class has to have features of independant classes. A class is created by inheriting or combining two or more completely different super-classes.
* This is used when a class has to have features of independant classes. A class is created by inheriting or combining two or more completely different [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)#Subclasses_and_superclasses super-classes].
* For example, in Eiffel, the library class WINDOW is a subclass of SCREENMAN, RECTANGLE, and TWO_WAY_TREE.
* For example, in Eiffel, the library class WINDOW is a [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)#Subclasses_and_superclasses subclass] of SCREENMAN, RECTANGLE, and TWO_WAY_TREE.


Example:
Example:
Line 699: Line 698:
</pre>
</pre>
'''3. Submodularity'''
'''3. Submodularity'''
* Modularity of the sub-parts of the classes is noticed and factored out into subclasses.  
* Modularity of the sub-parts of the classes is noticed and factored out into [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)#Subclasses_and_superclasses subclasses].  
* This is used when the super-classes are modular and the modularity has to be factored out into subclasses. For example, in a class representing Interest rates, one might factor out FIXED_RATE and VARYING Interest rates.
* This is used when the super-classes are modular and the modularity has to be factored out into [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)#Subclasses_and_superclasses subclasses]. For example, in a class representing Interest rates, one might factor out FIXED_RATE and VARYING Interest rates.


Example
Example
Line 733: Line 732:


'''4. Separation of interface and implementation'''
'''4. Separation of interface and implementation'''
* Interfaces are defined by Abstract Classes. Interfaces contain a group of related method declarations.  
* [http://en.wikipedia.org/wiki/Interface_(Java) Interfaces] are defined by [http://en.wikipedia.org/wiki/Abstract_type Abstract Classes]. Interfaces contain a group of related method declarations.  
* The methods are not defined in the Interfaces. Interfaces represents the super-class and the sub-classes inherit the interfaces by implementing the interfaces.  
* The methods are not defined in the Interfaces. Interfaces represents the [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)#Subclasses_and_superclasses super-class] and the [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)#Subclasses_and_superclasses sub-classes] inherit the interfaces by implementing the interfaces.  
* In other words, the subclasses encapsulate the implementation details of the interface.
* In other words, the subclasses encapsulate the implementation details of the interface.
* For example, a Stack class could be created as a subclass of StackInterface and StackImplementation.
* For example, a Stack class could be created as a subclass of StackInterface and StackImplementation.
Line 755: Line 754:
>> abstract method
>> abstract method
</pre>
</pre>
 
=== Disadvantages of Multiple Inheritance ===
=== Disadvantages of Multiple Inheritance ===
 


* Programmers use multiple inheritance to increase reusability and consistency in the system.
* Programmers use multiple inheritance to increase reusability and consistency in the system.
Line 832: Line 829:


* This problem is similar to the name collision issue discussed above.  
* This problem is similar to the name collision issue discussed above.  
* An object may need to execute a method (for example, initialize()) which has been defined in different super-classes.  
* An object may need to execute a method (for example, [http://www.rubyist.net/~slagell/ruby/objinitialization.html initialize()]) which has been defined in different super-classes.  
* The method resolution becomes a problem during compile time and can lead to run-time errors.
* The method resolution becomes a problem during [http://en.wikipedia.org/wiki/Compile_time compile time] and can lead to [http://en.wikipedia.org/wiki/Run_time_(program_lifecycle_phase) run-time errors].
Example
Example
Consider the example TeachingAssistant example of multiple inheritance discussed in csc517 class. Even though the program works fine, consider the situation when, user wants to access to_s method of person / student fter declaring to_s in teaching_assistant class?!
Consider the example TeachingAssistant example of multiple inheritance discussed in csc517 class. Even though the program works fine, consider the situation when, user wants to access to_s method of person / student fter declaring to_s in teaching_assistant class?!
Line 909: Line 906:
* Multiple inheritance provides the ability to a sub-class to inherit from a parent class as many times as it wants. Also, a sub-class can inherit from as many parent classes as it wants.  
* Multiple inheritance provides the ability to a sub-class to inherit from a parent class as many times as it wants. Also, a sub-class can inherit from as many parent classes as it wants.  
* Therefore, there is a chance that inheritance is used more often than is needed unnecessarily.
* Therefore, there is a chance that inheritance is used more often than is needed unnecessarily.
* For example, consider a new ApplePie class which has to inherit features from Apple class and Cinnamon class. Programmers may consider this multiple inheritance because ApplePie contains Apple and Cinnamon. But, this is not the right way. Whenever a class wants to inherit another class, there should be a "is-a" relationship between the sub-class and super-class. Here, there is a "has-a" relation and not "is-a" relationship.
* For example, consider a new ApplePie class which has to inherit features from Apple class and Cinnamon class. Programmers may consider this multiple inheritance because ApplePie contains Apple and Cinnamon. But, this is not the right way. Whenever a class wants to inherit another class, there should be a [http://it.toolbox.com/wiki/index.php/'is_a'_relationship_and_a_'has_a'_relationship_in_Java "is-a"] relationship between the sub-class and super-class. Here, there is a [http://it.toolbox.com/wiki/index.php/'is_a'_relationship_and_a_'has_a'_relationship_in_Java "has-a"] relation and not "is-a" relationship.
* ApplePie has-a Apple
* ApplePie has-a Apple
* ApplePie has-a Cinnamon
* ApplePie has-a Cinnamon
Line 940: Line 937:
   feature....
   feature....
Here, the inherit clause would be illegal without the rename clause. This ensures that name conflicts are resolved. This also allows the programmer to give meaningful and appropriate names to the inherited features.
Here, the inherit clause would be illegal without the rename clause. This ensures that name conflicts are resolved. This also allows the programmer to give meaningful and appropriate names to the inherited features.


==  Specifying Objects ==
==  Specifying Objects ==
Line 955: Line 950:


Let us compare and contrast between Set based language - object specification and Protocol based language - object specification
Let us compare and contrast between Set based language - object specification and Protocol based language - object specification
 
{| class="wikitable" border="1"
Set based language - object specification Protocol based language - object specification
|-
First, a class is described which abstracts the features or properties of the object we want to specify. First, an object that is a concrete representation of the object we are trying to specify is created. This is the prototype.
! Set based language - object specification
After describing the template or class, instances or objects for that class are created to perform the actual work. Classes can be described by Meta-classes. Multiple instances of that object are obtained by copying or cloning.
! Protocol based language - object specification
Every object instance for a class is unique and holds its internal values for all the features defined for that class. Each and every instance has those properties and internal values that are specific and unique to itself and a reference to its prototype, called an extension.
|-
Essentially, there is no distinction between an instance and a prototype. Any instance can be copied or cloned to become the prototypical object for its duplicates.
| First, a class is described which abstracts the features or properties of the object we want to specify.
 
| First, an object that is a concrete representation of the object we are trying to specify is created. This is the prototype.
|-
| After describing the template or class, instances or objects for that class are created to perform the actual work. Classes can be described by Meta-classes.  
| Multiple instances of that object are obtained by copying or cloning.  
|-
| Every object instance for a class is unique and holds its internal values for all the features defined for that class. Each and every instance has those properties and internal values that are specific and unique to itself and a reference to its prototype, called an extension.  
| Essentially, there is no distinction between an instance and a prototype. Any instance can be copied or cloned to become the prototypical object for its duplicates.
|
|}




Line 992: Line 995:




* In a prototype-based object specification system, the objects are defined using a bottom-up approach by first specifying the specific instance and modifying it as necessary to represent other instances.
* In a prototype-based object specification system, the objects are defined using a [http://en.wikipedia.org/wiki/Top-down_and_bottom-up_design bottom-up] approach by first specifying the specific instance and modifying it as necessary to represent other instances.


* Consider the same car example. To describe a car Mercedes, we create an object first that contains its properties (Mercedes logo, black, sedan, fast).
* Consider the same car example. To describe a car Mercedes, we create an object first that contains its properties (Mercedes logo, black, sedan, fast).
Line 1,013: Line 1,016:
* We can then perform inheritance and define sub-classes, modify or add more functionality and create instances for the sub-classes.  
* We can then perform inheritance and define sub-classes, modify or add more functionality and create instances for the sub-classes.  
* The sub-class objects receive messages. If they don't understand, they consult the ancestors in the inheritance hierarchy.
* The sub-class objects receive messages. If they don't understand, they consult the ancestors in the inheritance hierarchy.
* The include statement can be used to augment the class definition and add more functionality to the class.
* The [http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html include] statement can be used to augment the class definition and add more functionality to the class.




Line 1,027: Line 1,030:
* There is a way in Ruby, to add instance specific functionality to just specific instances/objects of a class by using the object#extend method.
* There is a way in Ruby, to add instance specific functionality to just specific instances/objects of a class by using the object#extend method.
* This means, some objects of a class can have values for all the properties mentioned in the class, but a few others can have additional properties specific to them. This concept is called Extending Objects.
* This means, some objects of a class can have values for all the properties mentioned in the class, but a few others can have additional properties specific to them. This concept is called Extending Objects.
* The example below, which is taken from the Class notes of CSC517, NCSU illustrates the concept of extending specific objects.
* The example below, which is taken from the [http://courses.ncsu.edu/csc517//common/lectures/notes/lec6.pdf Class notes of CSC517, NCSU] illustrates the concept of extending specific objects.
* Consider a Person class which has properties for a mild-mannered people.
* Consider a Person class which has properties for a mild-mannered people.
<pre>
<pre>
Line 1,069: Line 1,072:
</pre>
</pre>
Here, we have two situations. Some objects of the person class are mild-mannered, while some other objects of the same person class have super powers with them.
Here, we have two situations. Some objects of the person class are mild-mannered, while some other objects of the same person class have super powers with them.
Extending Objects - example
[http://positiveincline.com/index.php/2009/06/dynamically-extending-object-behaviour-in-ruby-and-python-a-quick-warts-and-all-comparison/ Extending Objects] - example
* To achieve this, if we add super power functionality to the person class itself, then all the mild-mannered person objects will also ending having values for this property.  
* To achieve this, if we add super power functionality to the person class itself, then all the mild-mannered person objects will also ending having values for this property.  
* If we use include to mix the SuperPowers module into the Person class, it will give every person super powers. Some people are bound to misuse such power.
* If we use include to mix the SuperPowers module into the Person class, it will give every person super powers. Some people are bound to misuse such power.
Line 1,123: Line 1,126:
==  References ==
==  References ==


Class notes of CSC517, NCSU
[http://courses.ncsu.edu/csc517//common/lectures/notes/lec6.pdf Class notes of CSC517, NCSU]
[1]
[1]
[2]
[2]
Line 1,134: Line 1,137:
http://www.informatics.susx.ac.uk/research/groups/nlp/datr/datrnode33.html  
http://www.informatics.susx.ac.uk/research/groups/nlp/datr/datrnode33.html  
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html  
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html  
Deadly Diamond of Death
[http://en.wikipedia.org/wiki/Diamond_problem Subclasses and Superclasses]
http://en.wikipedia.org/wiki/Diamond_problem Subclasses and Superclasses
[http://en.wikipedia.org/wiki/Mixin Mixins]
Mixins
http://en.wikipedia.org/wiki/Interface_%28Java%29  
http://en.wikipedia.org/wiki/Interface_%28Java%29  
Object Composition
[http://en.wikipedia.org/wiki/Object_composition Object Composition]
Is-a relatioship
[http://en.wikipedia.org/wiki/Is-a Is-a relatioship]
http://en.wikipedia.org/wiki/Eiffel_%28programming_language%29#Renaming  
http://en.wikipedia.org/wiki/Eiffel_%28programming_language%29#Renaming  
http://ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html
http://ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html
Line 1,152: Line 1,154:
==  External Links ==
==  External Links ==


Compile time
[http://en.wikipedia.org/wiki/Compile_time Compile time]
Run time
[http://en.wikipedia.org/wiki/Run_time Run time]
http://wiki.answers.com/Q/What_are_the_advantages_of_single_inheritance_over_multiple_inheritance  
http://wiki.answers.com/Q/What_are_the_advantages_of_single_inheritance_over_multiple_inheritance  
http://archive.eiffel.com/doc/manuals/technology/bmarticles/joop/multiple.html  
http://archive.eiffel.com/doc/manuals/technology/bmarticles/joop/multiple.html  
Ruby extend and Include
[http://railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/ Ruby extend and Include]
Ruby Multiple Inheritance with modules and mixins
[http://www.tutorialspoint.com/ruby/ruby_modules.htm Ruby Multiple Inheritance with modules and mixins]
http://download.oracle.com/javase/tutorial/java/IandI/abstract.html  
http://download.oracle.com/javase/tutorial/java/IandI/abstract.html  
http://download.oracle.com/javase/tutorial/java/IandI/usinginterface.html  
http://download.oracle.com/javase/tutorial/java/IandI/usinginterface.html  
Abstract types
[http://en.wikipedia.org/wiki/Abstract_type Abstract types]
http://en.wikipedia.org/wiki/Reusability  
http://en.wikipedia.org/wiki/Reusability  


Line 1,169: Line 1,171:
http://en.wikipedia.org/wiki/Ruby_%28programming_language%29  
http://en.wikipedia.org/wiki/Ruby_%28programming_language%29  
http://rubyonrails.org/  
http://rubyonrails.org/  
Object oriented Programming
[http://en.wikipedia.org/wiki/Object-oriented_programming Object oriented Programming]
Learn Ruby
[http://en.wikipedia.org/wiki/Ruby_(programming_language) Learn Ruby]
Functional programming
[http://en.wikipedia.org/wiki/Functional_programming Functional programming]
Imperative Programming
[http://en.wikipedia.org/wiki/Imperative_programming Imperative Programming]
Interpreted language
[http://en.wikipedia.org/wiki/Interpreted_language Interpreted language]
Reflection
[http://en.wikipedia.org/wiki/Reflection_(computer_programming) Reflection]
Dynamic language
[http://en.wikipedia.org/wiki/Dynamic_programming_language Dynamic language]
Python
[http://en.wikipedia.org/wiki/Python_(programming_language) Python]
Perl
[http://en.wikipedia.org/wiki/Perl Perl]
Ruby on Rails
[http://en.wikipedia.org/wiki/Ruby_on_Rails Ruby on Rails]
Model View Controller - MVC
[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller Model View Controller - MVC]
Metaprogramming Ruby: Program Like the Ruby Pros
[http://en.wikipedia.org/wiki/Metaprogramming Metaprogramming Ruby: Program Like the Ruby Pros]
Design Patterns in Ruby
[http://designpatternsinruby.com/ Design Patterns in Ruby]
Garbage Collection in Ruby
[http://www.rubyinside.com/how-ruby-manages-memory-and-garbage-collection-3006.html Garbage Collection in Ruby]
Threads in Ruby
[http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html Threads in Ruby]
Ruby interface to C modules
Currying

Latest revision as of 09:29, 19 November 2012

Modules and Mixins


Regular Expressions

Definition

  • Regular expressions are extremely powerful.Rubywas built as a better Perl hence it supports regular expressions.
  • Regular expression is sort of a string used to match to other strings.In ruby regular expressions are written in the format /pattern/modifiers where pattern is the regular expression and modifiers are the series of characters specifying the various options.
  • To understand the power of regular expressions here is an example.


Regexp objects

  • In Ruby there is "Regexp" which is a Ruby object representing a Regular expression.Creating a Regexp object is similar to creating a string except for the usage of a forward slash to delimit it,rather than quote marks.

r = /my regular expression/


Replace

  • In the following example the character 'c' is replaced with "".

"faculty".sub(/c/, "") >> "faulty"


Search

  • The regular expressions will match the string "my regular expression" anywhere in the string.Let's look at what we can put into regular expressions using Regexp. Here's an example to retrieve the first match of /w.ll/ in the string.
string1="I will drill for a well for you"
=> "I will drill for a well for you"
r=Regexp.new(/w.ll/)
=> /w.ll/
r.match(string1)
=> #<MatchData "will">

Suppose you want to retrieve the first digit in a string.Here's an example:

e4=Regexp.new('\d')
=> /\d/
string="hello12 123"
=> "hello12 123"
e4.match(string)
=> #<MatchData "1">
	

The above example since \d matches only digits it selects the 1 from Hello12.In order to retrieve the digits"12" from "hello12" we need to use \w which recognizes all word character[0-9A-Z a-z_] .Here's an example showing it.

e4=Regexp.new('\d\w*')
=> /\d\w*/
e4.match(string)
=> #<MatchData "12">

List of commonly used Regular expressions

The table below represents some special characters and their meaning in the patterns.

Regex- Character	Meaning
(...)	Capture everything enclosed
(a|b)	a or b
a?	Zero or one of a
a*	Zero or more of a
a+	One or more of a
a{3}	Exactly 3 of a
a{3,}	3 or more of a
a{3,6}	Between 3 and 6 of a
.	Any single character
\s	Any whitespace character
\S	Any non-whitespace character
\d	Any digit
\D	Any non-digit
\w	Any word character (letter, number, underscore)
\W	Any non-word character
\b	Any word boundary
[abc]	A single character of: a, b or c
[^abc]	Any single character except: a, b, or c
[a-z]	Any single character in the range a-z
[a-zA-Z]	Any single character in the range a-z or A-Z
^	Start of line
$	End of line
\A	Start of string
\z	End of string
options: i case insensitive m make dot match newlines x ignore whitespace in regex 
o perform #{...} substitutions only once

More Examples

Example Description

/([Rr])uby&\1ails/	Match ruby&rails or Ruby&Rails
/(['"])(?:(?!\1).)*\1/	Single or double-quoted string. \1 matches whatever the 1st group matched . \2 matches whatever the 2nd group matched, etc.

Example Description

/^Ruby/	Match "Ruby" at the start of a string or internal line
/Ruby$/	Match "Ruby" at the end of a string or line
/\ARuby/	Match "Ruby" at the start of a string
/Ruby\Z/	Match "Ruby" at the end of a string
/\bRuby\b/	Match "Ruby" at a word boundary
/\brub\B/	\B is nonword boundary: match "rub" in "rube" and "ruby" but not alone
/Ruby(?=!)/	Match "Ruby", if followed by an exclamation point
/Ruby(?!!)/	Match "Ruby", if not followed by an exclamation point

Example

line1 = "Cats are smarter than dogs";
line2 = "Dogs also like meat";
if ( line1 =~ /Cats(.*)/ )
  puts "Line1 starts with Cats"
end
if ( line2 =~ /Cats(.*)/ )
  puts "Line2 starts with Dogs"
end

This will produce following result:
Line1 starts with Cats

Example

text = "rails are rails, really good Ruby on Rails"
# Change "rails" to "Rails" throughout
text.gsub!("rails", "Rails")
# Capitalize the word "Rails" throughout
text.gsub!(/\brails\b/, "Rails")
puts "#{text}"
This will produce following result:
Rails are Rails, really good Ruby on Rails
	

Modules and Mixins

Modules

Definition

  • Ruby Modules are similar to classes in that they hold a collection of methods,constants and other module and class definitions.
  • Modules definition is similar to classes just that we use the keyword module instead of the class keyword.

How Modules differ from classes?

Unlike classes, objects cannot be created based on modules nor can it be sub classed.However, it can be specified that the functionality of one module should be added to another class, or a specific object.

Uses of modules

Modules serve two purpose: 1.They act as namespace in C++, letting definition of methods whose names will not clash with those defined elsewhere. 2.Modules allow to share functionality between classes.


Example

  • Here's an example taken from class notes Class notes of CSC517, NCSU to illustrate modules.
  • Suppose there is a graphics library that contains classes for Windows(windows.rb) and Border(border.rb).Window.rb and border.rb have a top method,which gives the position of the top of the Windows and top of the border respectively.
  • To layout windows with borders,both windows.rb and border.rb have to be loaded into the program.However, as the top method is in both classes one of them will be overridden.
  • The solution to this is use of modules. The window function and border function can go into separate modules respectively.
module Window 
def Window.top 
# .. 
end 
def Window.bottom 
# .. 
end 
end 

module Border 
def Border.top 
# ... 
end 
def Border.width 
# .. 
end
end

When a program needs to use these modules, it can simply load the two files using the Ruby [http://ruby.about.com/od/rubyfeatures/a/require.htm require] statement, and reference the qualified names.

 
require 'window' 
require 'border' 
trueTop = Window.top + Border.Top.

Mixins

Definition

  • The most interesting fact about the use of modules is to define mixins. When a module is included within a class,all its functionality becomes available to the class.
  • Modules can contain class methods and instance methods.

How mixinsis different from #include and multiple inheritance?

  • Let's see how mixinsis contrasting to #include and multiple inheritance in other languages.#include files define methods that can be called but not applied to objects.
  • By using mixinsthe same methods can be added to any number of different classes;regardless of hierarchy.
  • mixinscorresponds to the usage of interfaces in Java.


Example

Consider the following example taken from class notes [http://courses.ncsu.edu/csc517//common/lectures/notes/lec6.pdf Class notes of CSC517, NCSU] to illustrate mixins.

 
module Introspect 
  def kind 
    puts "#{self.class.name}" 
  end 
end 

class Animal 
  include Introspect 
  def initialize(name) 
     @name = name 
  end 
end 

class Car 
  include Introspect 
  def initialize(model) 
    @model = model 
  end 
end 
d = Animal.new("Cat") 
c = Car.new("Ferrari") 
d.kind # kind method is available through … 
c.kind # .. the mixin Introspect 
>>Animal 
>>Car 

Consider another example to understand mixins better.


module Persistence
  def load sFileName
   puts "load code to read #{sFileName} contents into my_data"
  end
 def save sFileName
  puts "Uber code to persist #{@my_data} to #{sFileName}"
 end
 def kind
  puts "#{self.class.name}"
 end
end

class BrandNewClass
    include Persistence
    attr :my_data

        def data=(someData)
        @my_data = someData
    end
end
b = BrandNewClass.new
b.data = "My pwd"
b.save "MyFile.secret"
Uber code to persist My pwd to MyFile.secret
b.kind
>>BrandNewClass

Similar functionality in other OO languages

Namespace in C++ (similar to modules)

Definition
  • In general, a namespace is a container for a set of identifiers (names), and allows the disambiguation of homonym identifiers residing in different namespaces.
  • Namespace usually group names based on their functionality.


Steps involved

To use C++ namespaces, there are two steps involved:

  • To uniquely identify a namespacewith the keyword namespace.
  • To access the elements of an identified namespace by applying the using keyword.


Example

namespace  NewOne
{
      int p;
      long q
}
*	p and q are normal variables but integrated within the NewOne [http://en.wikipedia.org/wiki/Namespace namespace].  
*	In order to access this variables from the outside the [http://en.wikipedia.org/wiki/Namespace namespace], we have to use the scope operator ::. 
*	From previous example:

NewOne::p;
NewOne::q;

A namespace definition can be nested within another [http://en.wikipedia.org/wiki/Namespace namespace]definition.  Every namespace definition must appear either at file scope or immediately within another namespace definition.  For example:

// a namespace with using directive
#include <iostream>
using namespace std;
namespace SampleOne
{
       float p = 10.34;
}
 
namespace SampleTwo
{
       using namespace SampleOne;
       float q = 77.12;
       namespace InSampleTwo
       {
              float r = 34.725;
       }
}
 
int main()
{
       // this directive gives you everything declared in SampleTwo
       using namespace SampleTwo;
       // this directive gives you only InSampleTwo
       using namespace SampleTwo::InSampleTwo;
       // local declaration, take precedence
       float p = 23.11;
 
       cout<<"p = "<<p<<endl;
       cout<<"q = "<<q<<endl;
       cout<<"r = "<<r<<endl;
       return 0;
}

Multiple inheritance (C++ only) (similar to mixins)

Definition

You can derive a class from any number of base classes. Deriving a class from more than one direct base class is called multiple inheritance.


Example
 
In the following example, classes A, B, and C are direct base classes for the derived class X:
class A { /* ... */ };
class B { /* ... */ };
class C { /* ... */ };
class X : public A, private B, public C { /* ... */ };
The following inheritance graph describes the inheritance relationships of the above example. An arrow points to the direct base class of the class at the tail of the arrow:
 
 

The order of derivation is relevant only to determine the order of default [http://en.wikipedia.org/wiki/Initialization_(programming) initialization] by [http://en.wikipedia.org/wiki/Constructor constructors] and cleanup by [http://en.wikipedia.org/wiki/Destructor_(computer_programming) destructors].
A direct base class cannot appear in the base list of a derived class more than once:
class B1 { /* ... */ };                   // direct base class
class D : public B1, private B1 { /* ... */ }; // error
However, a derived class can inherit an indirect base class more than once, as shown in the following example:
 
class L { /* ... */ };                  // indirect base class
class B2 : public L { /* ... */ };
class B3 : public L { /* ... */ };
class D : public B2, public B3 { /* ... */ }; // valid
*	In the above example, class D inherits the indirect base class L once through class B2 and once through class B3.
*	However, this may lead to ambiguities because two subobjects of class L exist, and both are accessible through class D. 
*	You can avoid this ambiguity by referring to class L using a qualified class name. For example:
B2::L
or
B3::L.
You can also avoid this ambiguity by using the base specifier virtual to declare a base class, as described in Derivation (C++ only).

Interface (Java) (similar to mixins)

Definition
  • A Java interface defines a set of methods but does not implement them.
  • A class that implements the interface agrees to implement all of the methods defined in the interface, thereby agreeing to certain behavior, thereby implementing multiple inheritance.
Properties of Interface:
  • An interface is implicitly abstract. You do not need to use the abstract keyword when declaring an interface.
  • Each method in an interface is also implicitly abstract, so the abstract keyword is not needed.
  • Methods in an interface are implicitly public.
Example
*	When a class implements an [http://en.wikipedia.org/wiki/Interface_(Java) interface], you can think of the class as signing a contract, agreeing to perform the specific behaviors of the interface. 
*	If a class does not perform all the behaviors of the [http://en.wikipedia.org/wiki/Interface_(Java) interface], the class must declare itself as abstract.
/* File name : Animal.java */
interface Animal {

	public void eat();
	public void travel();
}

*	A class uses the [http://www.roseindia.net/help/java/i/implement-keyword.shtml implements] keyword to implement an [http://en.wikipedia.org/wiki/Interface_(Java) interface]. The implements keyword appears in the class declaration following the extends portion of the declaration.
/* File name : MammalInt.java */
public class MammalInt implements Animal{

   public void eat(){
      System.out.println("Mammal eats");
   }

   public void travel(){
      System.out.println("Mammal travels");
   } 

   public int noOfLegs(){
      return 0;
   }

   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
} 
This would produce following result:
Mammal eats
Mammal travels

Comparable

Definition

  • The comparable mixin is used by classes whose objects may be ordered.
  • The class must define the <=> operator, which compares the receiver against another object,returning -1,0 or +1 depending on whether the receiver is less than,equal to ,or greater than the other object.
  • If the other object is not comparable then is should just return nil.comparableuses <=> to implement the comparison operators(<,<=,==,=>,and >) and the method between?.


Example

Here is an example taken from class notes [http://courses.ncsu.edu/csc517//common/lectures/notes/lec6.pdf Class notes of CSC517, NCSU] to illustrate [http://www.ruby-doc.org/core-1.9.3/Comparable.html comparable]mixin.

class Line 
  def initialize(x1, y1, x2, y2) 
    @x1, @y1, @x2, @y2 = x1, y1, x2, y2 
  end   
end 

We compare two lines on the basis of their lengths. We add the Comparable mixin as follows:

class Line  
  include Comparable  
  def length_squared 
    (@x2-@x1) * (@x2-@x1) + (@y2-@y1) * (@y2-@y1)
end
def <=>(other) 
    self.length_squared <=> other.length_squared 
  end 
end 

Spaceship operator

  • <=> returns 1,0, or –1, depending on whether the first argument is greater than, equal to, or less than the second argument.
  • We delegate the call to <=> of the Fixnum class, which compares the squares of the lengths. Now we can use the Comparable methods on Line objects:
 
l1 = Line.new(1, 0, 4, 3) 
l2 = Line.new(0, 0, 10, 10) 
puts l1.length_squared 
if l1 < l2 
  puts "Line 1 is shorter than Line 2" 
else if l1 > l2 
  puts "Line 1 is longer than Line 2" 
else 
  puts "Line 1 is just as long as Line 2" 
 end 
end 
>>Line 1 is shorter than Line 2

Enumerable

Definition

Enumerable is a standard mixin which can be used to put into other classes.It has a method called inject that can be applied to adjacent elements of a set.


Example

Consider the following example.

[1, 2, 3, 4, 5 ,6].inject {|v, n| v+n }
>>21
  • As seen in the above example inject is used on all elements of the set to add them and display the result.
  • To understand the working of Enumerablemixin in class,consider the following example taken from class notes Class notes of CSC517, NCSU. The class VowelFinder returns successive vowels in a string using the Enumerablemixin method.

class VowelFinder 
  include Enumerable 
  def initialize(string) 
    @string = string 
  end 
  def each 
    @string.scan(/[aeiou]/) do |vowel| 
      yield vowel 
    end 
  end 
end  


VowelFinder.new("abacadabra").inject {|v, n| v+n} 
>>aaaaa

Simulating Multiple Inheritance

  • Multiple Inheritance has several disadvantages that can lead to ambiguous code behavior either during compile time or run time.
  • Ruby does not support directMultiple Inheritance. But, Multiple Inheritance can be achieved in Ruby through Modules. Modules simulate multiple inheritance in Ruby.
  • Given below is the Taggable-string example taken from the Class notes of CSC517, NCSU. Suppose we want to add tags to Strings, we can define a Taggable module and include it into the class.


Example


 require 'set'      # A collection of unordered values with no duplicates
 
 module Taggable
   attr_accessor :tags
   
   def taggable_setup
     @tags = Set.new
   end
   
   def add_tag(tag)
     @tags << tag
   end
   
   def remove_tag(tag)
     @tags.delete(tag)
   end
 end
 
 class TaggableString < String
   include Taggable
   def initialize(*args)
     super
     taggable_setup
   end
 end
 
 s = TaggableString.new('It is a bright, it is a sunny day')
 s.add_tag 'sentence'
 s.add_tag 'quotation'
 s.tags                          # =>    #<Set: {"sentence", "quotation"}>

Given below is another simple example of how modules and mixins can be used to simulate multiple inheritance in Ruby.

 module A
   def a1
     puts "Inside a1"
   end
   def a2
     puts "Inside a2"
   end
 end
 
 module B
    def b1
      puts "Inside b1"
    end
    def b2
      puts "Inside b2"
    end
 end
 
 class Sample
   include A
   include B
   def s1
     puts "Inside s1"
   end
 end
 
 obj = Sample.new
 obj.a1             # => Inside a1
 obj.a2             # => Inside a2
 obj.b1             # => Inside b1
 obj.b2             # => Inside b2
 obj.s1             # => Inside s1

Advantages of Multiple Inheritance

Although multiple inheritance has its disadvantages, there are a couple of good reasons for using multiple inheritance. Generally, multiple inheritance is used in one of the following ways:

1. Multiple Independant Protocols

  • This is used when a class has to have features of independant classes. A class is created by inheriting or combining two or more completely different super-classes.
  • For example, in Eiffel, the library class WINDOW is a subclass of SCREENMAN, RECTANGLE, and TWO_WAY_TREE.

Example: Our classification of objects in everyday life is naturally hierarchical. We know that all cats are mammals, and all mammals are animals. Smaller classes inherit characteristics from the larger classes to which they belong. If all mammals breathe, then all cats breathe.

class Mammal
def breathe
puts "inhale and exhale"
end
end

class Cat<Mammal
def speak
puts "Meow"
end
end

tama = Cat.new

tama.breathe
>> inhale and exhale

tama.speak
>> Meow

2. Mix and Match

  • This is used when a class need to created as a combination of different super-classes. Several classes are created specially for subsequent combination.
  • There is a mix and match of super-classes combined into a single sub-class. For example, Mixins help achieve this.

Example

module A
  def a1
    puts "Module A method a1"
  end
  def a2
    puts "Module A method a2"
  end
end
module B
  def b1
    puts "Module B method b1"
  end
  def b2
    puts "Module B method b2"
  end
end

class Sample
  include A
  include B
  def s1
    puts "Class method s1"
  end
end

samp=Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1
>> Module A method a1
Module A method a2
Module B method b1
Module B method b2
Class method s1

3. Submodularity

  • Modularity of the sub-parts of the classes is noticed and factored out into subclasses.
  • This is used when the super-classes are modular and the modularity has to be factored out into subclasses. For example, in a class representing Interest rates, one might factor out FIXED_RATE and VARYING Interest rates.

Example

 
class Calc
  def initialize x,y
    @x=x
    @y=y
  end

  def result
puts "product #{Product.result(@x,@y)}"
puts "Sum #{Sum.result(@x,@y)}"
  end
end
class Product
  def Product.result x,y
    x*y
  end
end
class Sum

  def Sum.result x,y
    x+y
  end
end
a= Calc.new 3,4
a.result
>> product 12
Sum 7

4. Separation of interface and implementation

  • Interfaces are defined by Abstract Classes. Interfaces contain a group of related method declarations.
  • The methods are not defined in the Interfaces. Interfaces represents the super-class and the sub-classes inherit the interfaces by implementing the interfaces.
  • In other words, the subclasses encapsulate the implementation details of the interface.
  • For example, a Stack class could be created as a subclass of StackInterface and StackImplementation.
  • In ruby Separation of interface and implementation is implemented as shown below.

Example:

class Shape
  def draw
    raise NotImplementedError.new(
              "Method not implemented")
  end
end
class Square < Shape
  def draw
    puts "abstract method"
  end
end

s = Square.new.draw
>> abstract method

Disadvantages of Multiple Inheritance

  • Programmers use multiple inheritance to increase reusability and consistency in the system.
  • Although multiple inheritance is useful, it can lead to ambiguity and increased complexity if not used carefully. For this reason, some languages like Java, Ruby etc., do not support direct multiple inheritance.
  • They provide different ways to achieve multiple inheritance like Interfaces, Mixins etc. The problems that arise due to multiple inheritance are as follows:

1. Name collision

  • Two features (instance variables or methods) with the same name are inherited from different super-classes.
  • The super-classes may be correct and consistent.
  • But the conflict arises when the sub-class inherit the two super-classes which have methods of the same name (for example, initialize()).
  • Some people call this situation the "Deadly Diamond of Death". This is illustrated by the Java code example below:
 // This is our top most abstract class.
 class AbstractSuperClass{
   abstract void method();
 }
 
 // These are the two concrete sub classes which extend the above super class
 class ConcreteSubOne extends AbstractSuperClass{
   void method(){
     System.out.println("I am going to test multiple Inheritance");
   }
 }
 
 class ConcreteSubTwo extends AbstractSuperClass{
   void method(){
     System.out.println("I will cause the Deadly Diamond of Death");
   }
 }

 // This is our last class which extends both of the above concrete classes
 class DeadlyDiamondEffect extends ConcreteSubOne, ConcreteSubTwo{
   //Some methods of this class
   //This inherits a do() method from ConcreteSubOne and another do() from ConcreteSubTwo. When this is called there is an ambiguity.
 }

2. Repeated inheritance

  • Multiple inheritance may result in a sub-class inheriting the same super-class more than once.
  • Since there are multiple paths from the sub-class to its ancestor classes, a class can by mistake, end up inhering the same super-class more than once. This can go unnoticed and lead to ambiguity and increase the chances of errors. It is very difficult to trace the errors as well.

Example

module A
  def a1
    puts "Module A method a1"
  end
  def a2
    puts "Module A method a2"
  end
end

class A1
  include A
  def a1
    puts "Module A1 method a1"
  end
  def a2
    puts "Module A1 method a2"
  end
end

class Sample < A1
  include A
  def s1
    puts "Class method s1"
  end
end

Here Sample class uses / mixes unnecessarily repeatedly methods of module A

3. Method combination

  • This problem is similar to the name collision issue discussed above.
  • An object may need to execute a method (for example, initialize()) which has been defined in different super-classes.
  • The method resolution becomes a problem during compile time and can lead to run-time errors.

Example Consider the example TeachingAssistant example of multiple inheritance discussed in csc517 class. Even though the program works fine, consider the situation when, user wants to access to_s method of person / student fter declaring to_s in teaching_assistant class?!

module Person
  attr_accessor :name
  attr_accessor :height
  attr_accessor :weight
  def to_s
    "Person[" + @name + ", height = " + @height + ", weight =" + weight + "]"
  end
end

module Student
  include Person
  attr_accessor :major
  attr_accessor :hometown
  def to_s
    "Student[" + @name + ", height = " + @height + 
    ", weight = " + weight + ", major = " + major + 
    ", hometown = " + hometown + "]"
    end
end

module Employee
  attr_accessor :title
  attr_accessor :wage
  include Person
  def to_s
    "Employee[" + @name + ", height = " + @height + 
    ", weight = " + weight + ", title = " + title + 
    ", wage = " + wage+ "]"
   end
end

class TeachingAssistant
include Student
include Employee
  def to_s
    "TeachingAssistant[" + @name + ", height = " + @height + 
    ", weight = " + weight + ", \n   major = " + major + 
    ", hometown = " + hometown + ", title = " + title + 
    ", wage = " + wage + "]"
   end
end

john = TeachingAssistant.new();
john.name = "John"
john.height = "6 ft. 2 in."
john.weight = "180 lbs."
john.major = "CS"
john.hometown = "Springfield"
john.title = "busboy"
john.wage = "$7.25/hr."
john.to_s


4. Implementation difficulties


  • Multiple inheritance can result in increased code complexity and implementation difficulties.
  • In multiple inheritance classes can be combined in several different ways. It becomes difficult for the programmer to represent different objects.
  • Finding methods needs a lot of search or redirection along the hierarchy.

Consider the below situation where class E inherits A through B C D, if E wishes to access methods of A, which route will class E follow to inherit the methods of A?



5. Misuse


  • Multiple inheritance provides the ability to a sub-class to inherit from a parent class as many times as it wants. Also, a sub-class can inherit from as many parent classes as it wants.
  • Therefore, there is a chance that inheritance is used more often than is needed unnecessarily.
  • For example, consider a new ApplePie class which has to inherit features from Apple class and Cinnamon class. Programmers may consider this multiple inheritance because ApplePie contains Apple and Cinnamon. But, this is not the right way. Whenever a class wants to inherit another class, there should be a "is-a" relationship between the sub-class and super-class. Here, there is a "has-a" relation and not "is-a" relationship.
  • ApplePie has-a Apple
  • ApplePie has-a Cinnamon
  • The relationship can be a object composition but not inheritance.
  • "Is-a" relationship does not exist. The thumb rule to check if inheritance is allowed is to verify the "is-a" relationship.


Resolution of Name conflicts or Collisions

Multiple inheritance may cause name conflicts when a sub-class inherits different super-classes that contain the methods or variables with the same name. This can be resolved in many ways.


Compound selectors in Ruby

Suppose a class Sub inherits two different methods for MethodOne from two different super-classes, SuperClassOne and SuperClassTwo. In Ruby, we can use Compound Selectors to refer to the method as shown below:

SuperClassOne.MethodOne      #Uses the MethodOne method inherited from SuperClassOne
SuperClassTwo.MethodOne      #Uses the MethodOne method inherited from SuperClassTwo


Renaming in Eiffel

In Eiffel language, naming conflicts are overcome in inherited features by renaming. It contains a rename clause to remove name conflicts. This is illustrated below:

Class Sub inherit
  SuperClassOne rename x as x1, y as y1;
  SuperClassTwo rename x as x2, y as y2;
  feature....

Here, the inherit clause would be illegal without the rename clause. This ensures that name conflicts are resolved. This also allows the programmer to give meaningful and appropriate names to the inherited features.

Specifying Objects

The Object-Oriented programming paradigm has two ways for specifying objects.

Set based language - object specification Protocol based language - object specification


Comparison between Set based language and Protocol based language

Let us compare and contrast between Set based language - object specification and Protocol based language - object specification

Set based language - object specification Protocol based language - object specification
First, a class is described which abstracts the features or properties of the object we want to specify. First, an object that is a concrete representation of the object we are trying to specify is created. This is the prototype.
After describing the template or class, instances or objects for that class are created to perform the actual work. Classes can be described by Meta-classes. Multiple instances of that object are obtained by copying or cloning.
Every object instance for a class is unique and holds its internal values for all the features defined for that class. Each and every instance has those properties and internal values that are specific and unique to itself and a reference to its prototype, called an extension. Essentially, there is no distinction between an instance and a prototype. Any instance can be copied or cloned to become the prototypical object for its duplicates.


Inheritance in Set based language - object specification

  • When the object that receives a message to perform some action, if it does not understand, it consults its ancestor classes asking each of them to handle the message along the inheritance hierarchy.


Example:

  • In a set-based object specification system, the objects are defined using a top-down approach by first specifying the abstract and using that abstract to create the specific.
  • To describe a car object, we collect properties that are common to all the cars and create a car class that

represents all cars and contains features that all cars should have.

  • Then we use that car class to create new car objects or instances.



Inheritance in Protocol based language - object specification

  • When an object receives a message, if it does not understand the message, the message is delegated to its prototypes asking each one of them to grant it the ability to handle the message.


Example:

  • In a prototype-based object specification system, the objects are defined using a bottom-up approach by first specifying the specific instance and modifying it as necessary to represent other instances.
  • Consider the same car example. To describe a car Mercedes, we create an object first that contains its properties (Mercedes logo, black, sedan, fast).
  • If we later discover a new car Lexus (Lexus logo, white), we specify what we know about Lexus and assume that the remainder in identical to the prototypical car Mercedes.
  • This may evolve the assumption that all cars are sedans and fast.


Extending specific objects

Ruby as a set-based language

  • Ruby can act as a set-based language.
  • We can first define classes that form the blueprint or a template.
  • We can then create instances for the classes. These objects contain internal values for the properties present in the class.
  • We can then perform inheritance and define sub-classes, modify or add more functionality and create instances for the sub-classes.
  • The sub-class objects receive messages. If they don't understand, they consult the ancestors in the inheritance hierarchy.
  • The include statement can be used to augment the class definition and add more functionality to the class.


Ruby as a prototype-based language

  • Ruby can also act as a prototype-based language. This is where specific instances of the class, not all, will have some unique features and properties.


Extending Objects


  • There is a way in Ruby, to add instance specific functionality to just specific instances/objects of a class by using the object#extend method.
  • This means, some objects of a class can have values for all the properties mentioned in the class, but a few others can have additional properties specific to them. This concept is called Extending Objects.
  • The example below, which is taken from the Class notes of CSC517, NCSU illustrates the concept of extending specific objects.
  • Consider a Person class which has properties for a mild-mannered people.
 class Person
   attr_reader :name, :age, :occupation
   
   def initialize(name, age, occupation)
     @name, @age, @occupation = name, age, occupation
   end
   
   def mild_mannered?
     true
   end
 end
 
 Amy = Person.new('Amy Wilson', 23, 'student')
 John = Person.new('John Mason', 40, 'professor')
 Amy.mild_mannered?                                  # => true 
 John.mild_mannered?                                 # => true

The above class describes all the people who are mild-mannered. What if there are some other people who are not as mild-mannered as they appear. That is they have some super-powers as well.

 module SuperPowers
   def fly
     'Flying!'
   end
   
   def leap(what)
     "Leaping #{what} in a single bound!"
   end
   
   def mild_mannered?
     false
   end
   
   def superhero_name
     'Superman'
   end
 end

Here, we have two situations. Some objects of the person class are mild-mannered, while some other objects of the same person class have super powers with them. Extending Objects - example

  • To achieve this, if we add super power functionality to the person class itself, then all the mild-mannered person objects will also ending having values for this property.
  • If we use include to mix the SuperPowers module into the Person class, it will give every person super powers. Some people are bound to misuse such power.

The only way to achieve this is to extend only those objects that have super powers instead of extending the entire class itself.

 Amy.extend(SuperPowers)
 puts Amy.superhero_name          # => Superman
 puts Amy.fly                     # => Flying!
 puts Amy.leap(rocks)             # => Leaping #{what} in a single bound!   
 puts Amy.mild_mannered?          # => false             
 puts John.mild_mannered?         # => true

Given below is another example that illustrates extending specific objects.

 module CarAction
   def goLeft(steps)
     Movement.new(self, steps)
   end
 end  
 
 
 #The Actions module can be included to allow a class to generate movements.
 class BigCar
   include CarAction
   def carMethod
     puts "This is a method inside BigCar class"
   end
 end
 
 #After CarActions is included goLeft can be executed by any instance of BigCar.
 car1 = BigCar.new
 car1.carMethod
 movement1 = car1.goLeft
 
 
 #The CarActions module is not included in the SmallCar class.
 class SmallCar
   def carMethod
     puts "This is a method inside SmallCar class"
   end
 end
 
 #Extend adds the methods to one instance, not to all instances.
 car2 = SmallCar.new
 car2.extend CarActions
 movement2 = car.goLeft
 
 car3 = SmallCar.new
 movement3 = car.goLeft      #Error: car3 does not extend CarActions, hence cannot call the goLeft method.

References

Class notes of CSC517, NCSU [1] [2] [3] [4] [5] Multiple Inheritance [6] [7] http://www.informatics.susx.ac.uk/research/groups/nlp/datr/datrnode33.html http://csis.pace.edu/~bergin/patterns/multipleinheritance.html Subclasses and Superclasses Mixins http://en.wikipedia.org/wiki/Interface_%28Java%29 Object Composition Is-a relatioship http://en.wikipedia.org/wiki/Eiffel_%28programming_language%29#Renaming http://ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html http://rubular.com/ http://www.tutorialspoint.com/ruby/ruby_regular_expressions.htm http://www.tenouk.com/Module23.html http://en.wikipedia.org/wiki/Interface_(Java) http://www.tutorialspoint.com/java/java_interfaces.htm http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr134.htm


External Links

Compile time Run time http://wiki.answers.com/Q/What_are_the_advantages_of_single_inheritance_over_multiple_inheritance http://archive.eiffel.com/doc/manuals/technology/bmarticles/joop/multiple.html Ruby extend and Include Ruby Multiple Inheritance with modules and mixins http://download.oracle.com/javase/tutorial/java/IandI/abstract.html http://download.oracle.com/javase/tutorial/java/IandI/usinginterface.html Abstract types http://en.wikipedia.org/wiki/Reusability

See Also

http://www.ruby-lang.org/en/ http://www.ruby-lang.org/en/downloads/ http://en.wikipedia.org/wiki/Ruby_%28programming_language%29 http://rubyonrails.org/ Object oriented Programming Learn Ruby Functional programming Imperative Programming Interpreted language Reflection Dynamic language Python Perl Ruby on Rails Model View Controller - MVC Metaprogramming Ruby: Program Like the Ruby Pros Design Patterns in Ruby Garbage Collection in Ruby Threads in Ruby