CSC/ECE 517 Fall 2012/ch1 1w14 gv: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
m (Created page with "1w14: Advantages and disadvantages of multiple inheritance Multiple inheritance has been proposed as a way to avoid reimplementation of classes that need to include functiona...")
 
mNo edit summary
Line 1: Line 1:
1w14:    Advantages and disadvantages of multiple inheritance
== Introduction  ==


Multiple inheritance has been proposed as a way to avoid reimplementation of classes that need to include functionality from more than one ancestor class. But there are disadvantages, conceptually and in implementationThe debate over multiple inheritance has raged for yearsConsidering recent evidence, what are the advantages and disadvantages, and how important are each in practical and theoretical terms?  What are the alternatives to multiple inheritance, and how do they compare?
Multiple inheritance is one of the features of a few object-oriented (OO) languages in which a class inherits  properties (variables & methods) from more than one parent class . The former is called a sub or child class and the latter is called a super class or ancestor class. Multiple Inheritance extends the concept of single inheritance (where one sub class inherits the properties from one super class) to a paradigm where one child class will inherit properties from multiple parent classes.
 
For example, consider a class to describe teaching assistants. A TA class will draw a lot of properties from both Student and University employee classes. So, instead of implementing them again, we can programmatically specify that class TGradTeachingAsst extends both Student and Employee classes
 
This feature is supported by several object oriented languages such as C++, Eiffel, Perl, Python etc. On the other hand, some object oriented languages like C#, Smalltalk, Java, Modula-3, Objective C etc. do not support multiple inheritance.
Multiple inheritance is still a debatable feature in traditional object-oriented languages, as it has been omitted from languages like Java etc. Nonetheless, users of these languages often complain about having to work around the absence of multiple inheritance.
Multiple inheritance, if used wisely could be advantageous. On the other hand, if the developers are not smart enough to use it, it could lead to a lot of complexities.
 
 
==  Advantages ==
Multiple inheritance is widely considered a useful feature as it is commonly used in the above listed OO languages. It is also a frequently requested feature in languages that do not provide it. Programmers often devise their own workaround procedures to achieve what multiple inheritance offers. One of the advantages of multiple inheritance is that it obviates improvised solutions that would otherwise be
fairly obvious.
 
Following uses of multiple inheritance are desirable, all of which are supported :
 
1. Multiple specialization: An instance of a class that is derived by multiple inheritance can be conceptually thought of as a specialization of two different classes. For example, a class InputOutputStream is a specialization of both an InputStream and OutputStream.
In general, multiple inheritance allows us to combine classes to create new abstractions, and these new abstractions are of more value than the individual abstractions by themselves.
 
2. Multiple inheritance also helps in modeling relationships that are multi way. Without MI,
a choice has to be made among the many possible relationships, even though all of
them are valid. When a class needs properties found in more than one base class, MI
might be useful.
 
3. Multiple inheritance might lead to a higher possibility of code reuse. Every additional base class enhances code reuse. Without MI, we would be forced to use the has-a relationship, thereby reducing code reuse factor (increases implementation and testing time).
 
 
 
== Alternatives ==
 
a. Modules: A module is a collection of methods and constants. Modules can have no sub classes and instances. One of the major uses of modules is to encapsulate the methods and constants in one location. Modules provide namespace and also prevent name clashes. Ruby's built in modules like Math exhibit these features. For example,
Math::E gives the value of e(base of natural logarithms). The '::' operator tells the ruby interpreter which module it should look up for the value of E.
Syntax to define a module:
module <Module_Name>
//constants
//methods
  .
  .
end
Methods and constants in modules are declared just like they are declared in class.
Another use of modules is mixins.
 
b. Mixin inheritance: A mixin is a class that encapsulates additional attributes or properties which can be used by other classes. Mixins are typically narrow in scope (include only a few properties) and a class might inherit several mixins (for several properties). Mixins have a clear advantage in terms of modularity and reusability. Mixins cannot be instantiated independently (cannot stand on their own) and are not instantiated directly, as they might depend on the presence of a particular interface in the classes that inherit them. Generally, mixins are self contained.
Multiple Inheritance and Mixins differ in semantics. A class which uses multiple inheritance might utilize a mixin as a part of that multiple inheritance. Mixins can be thought of as an interface that is already implemented. We "include" a module in a class definition, its methods are effectively appended, or "mixed in" to the class.
Languages like C#, Perl, Python, Ruby take advantage of mixins. Languages like JavaScript do not support mixins but can copy methods from one object to other at run time thereby emulating mixins.
Following example shows how to use mixins in a class:
module A
  def a1
puts “Method a1”
  end
  def a2
puts “Method a2”
  end
end
module B
  def b1
puts “Method b1”
  end
  def b2
puts “Method b2”
  end
end
module C
  def c1
puts “Method c1”
  end
  def c2
puts “Method c2”
  end
end
class Example
include A
include B
  def e1
  end
end
exp = Example.new  // Creating a new object of Example class
exp.a1     // Calling a1 method of module A
exp.a2     // Calling a2 method of module A
exp.b1     // Calling b1 method of module B
exp.b2     // Calling b2 method of module B
exp.c1     // Calling c1 method of module C
exp.c2     // Calling c2 method of module C
exp.e1     // Calling e1 method defined inside class Example
 
Each module A, B and C have two methods a1, a2, b1, b2 and c1, c2 respectively. "include" is the keyword used in Ruby to embed a module in a class. The class Example includes modules A, B and C. Thus,  an object of the class Example can access all the methods in A, B and C modules. We can see that Example class shows multiple inheritance or a mixin.
 
 
 
== Comparison between C++/Java/Python/Ruby ==
 
Multiple Inheritance is supported by several object oriented languages such as C++, Ruby, Perl, Python etc. Let us compare how multiple inheritance is implemented in each of these languages.
 
C++
 
class Person
{
private:
    std::string m_strName;
    int m_nAge;
public:
    Person(std::string strName, int nAge,
        : m_strName(strName), m_nAge(nAge)
    {
    }
    std::string GetName()
    {
    return m_strName;
    }
    int GetAge()
    {
    return m_nAge;
    }
    bool IsMale()
    {
    return m_bIsMale;
    }
};
class Employee
{
private:
    std::string m_strEmployer;
    double m_dWage;
public:
    Employee(std::string strEmployer, double dWage)
        : m_strEmployer(strEmployer), m_dWage(dWage)
    {
    }
    std::string GetEmployer()
    {
    return m_strEmployer;
    }
    double GetWage()
    {
    return m_dWage;
    }
};
   
// Teacher publicly inherits Person and Employee
 
class Teacher: public Person, public Employee
{
private:
    int m_nTeachesGrade;
public:
    Teacher(std::string strName, int nAge, std::string strEmployer, double dWage, int nTeachesGrade)
        : Person(strName, nAge), Employee(strEmployer, dWage), m_nTeachesGrade(nTeachesGrade)
    {
    }
};
In C++, multiple inheritance is achieved by using the colon (:) operator to extend different base classes. In the above example, the "Teacher" class extends the properties of both Person and Employee classes. Thus, an object of "Teacher" class can use the public methods of both the "Person" and "Employee "classes.
 
 
Python
 
Python supports a limited form of multiple inheritance. The parent classes are included within parenthesis following the class name. The following example demonstrates multiple inheritance in Python:
class First(object):
    def __init__(self):
        print "first"
 
class Second(First):
    def __init__(self):
        print "second"
 
class Third(First):
    def __init__(self):
        print "third"
 
class Fourth(Second, Third):
    def __init__(self):
        super(Fourth, self).__init__()
        print "that's it"
 
In Python, parent method does not automatically get called. If methods are overriden, the parent version of method should be called. The keyword "super" is used to call the parent's method.
In the above Python example, class "Fourth" inherits classes "Second" and "Third" . The order in which classes are called in the above example is Fourth, Second, Third, First.
 
Ruby
Link to the mixin example
Java, another OO language, does not support multiple inheritance. But interfaces in Java can be used to emulate multiple inheritance. Java uses the "extends" keyword to inherit a base class and the keyword "implements" for interfaces.
interface I1 {
  abstract void test(int i);
}
interface I2 {
  abstract void test(String s);
}
public class C1 {
  public void test(float f) {
    float f = this.f;
  }
}
public class MultInterfaces extends C1 implements I1, I2 {
  public void test(int i) {
    System.out.println("In MultInterfaces.I1.test");
  }
  public void test(String s) {
    System.out.println("In MultInterfaces.I2.test");
  }
  public static void main(String[] a) {
    MultInterfaces t = new MultInterfaces();
    t.test(42); // calls the implemented interface I1 method
    t.test("Hello"); // calls the implemented interface I2 method
    t.test(1.42); // calls the class C1 method
  }
}
In Java, a class cannot extend two classes, but can implement more than 1 interfaces. The methods in the interfaces should be implemented by the class using them.
In the above example C1 is a parent class, I1 and I2 are interfaces with abstract methods. Objects of the MultInterfaces class can be created only if it implements abstract methods from interfaces I1 and I2.
7.        Code examples
References:
http://www.tutorialspoint.com/ruby/ruby_modules.htm
http://www.ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/modules.html
http://docs.python.org/tutorial/classes.html#multiple-inheritance
http://www.tutorialspoint.com/ruby/ruby_modules.htm

Revision as of 21:00, 14 September 2012

Introduction

Multiple inheritance is one of the features of a few object-oriented (OO) languages in which a class inherits properties (variables & methods) from more than one parent class . The former is called a sub or child class and the latter is called a super class or ancestor class. Multiple Inheritance extends the concept of single inheritance (where one sub class inherits the properties from one super class) to a paradigm where one child class will inherit properties from multiple parent classes.

For example, consider a class to describe teaching assistants. A TA class will draw a lot of properties from both Student and University employee classes. So, instead of implementing them again, we can programmatically specify that class TGradTeachingAsst extends both Student and Employee classes

This feature is supported by several object oriented languages such as C++, Eiffel, Perl, Python etc. On the other hand, some object oriented languages like C#, Smalltalk, Java, Modula-3, Objective C etc. do not support multiple inheritance. Multiple inheritance is still a debatable feature in traditional object-oriented languages, as it has been omitted from languages like Java etc. Nonetheless, users of these languages often complain about having to work around the absence of multiple inheritance. Multiple inheritance, if used wisely could be advantageous. On the other hand, if the developers are not smart enough to use it, it could lead to a lot of complexities.


Advantages

Multiple inheritance is widely considered a useful feature as it is commonly used in the above listed OO languages. It is also a frequently requested feature in languages that do not provide it. Programmers often devise their own workaround procedures to achieve what multiple inheritance offers. One of the advantages of multiple inheritance is that it obviates improvised solutions that would otherwise be fairly obvious.

Following uses of multiple inheritance are desirable, all of which are supported :

1. Multiple specialization: An instance of a class that is derived by multiple inheritance can be conceptually thought of as a specialization of two different classes. For example, a class InputOutputStream is a specialization of both an InputStream and OutputStream. In general, multiple inheritance allows us to combine classes to create new abstractions, and these new abstractions are of more value than the individual abstractions by themselves.

2. Multiple inheritance also helps in modeling relationships that are multi way. Without MI, a choice has to be made among the many possible relationships, even though all of them are valid. When a class needs properties found in more than one base class, MI might be useful.

3. Multiple inheritance might lead to a higher possibility of code reuse. Every additional base class enhances code reuse. Without MI, we would be forced to use the has-a relationship, thereby reducing code reuse factor (increases implementation and testing time).


Alternatives

a. Modules: A module is a collection of methods and constants. Modules can have no sub classes and instances. One of the major uses of modules is to encapsulate the methods and constants in one location. Modules provide namespace and also prevent name clashes. Ruby's built in modules like Math exhibit these features. For example, Math::E gives the value of e(base of natural logarithms). The '::' operator tells the ruby interpreter which module it should look up for the value of E. Syntax to define a module: module <Module_Name> //constants //methods

  .
  .

end Methods and constants in modules are declared just like they are declared in class. Another use of modules is mixins.

b. Mixin inheritance: A mixin is a class that encapsulates additional attributes or properties which can be used by other classes. Mixins are typically narrow in scope (include only a few properties) and a class might inherit several mixins (for several properties). Mixins have a clear advantage in terms of modularity and reusability. Mixins cannot be instantiated independently (cannot stand on their own) and are not instantiated directly, as they might depend on the presence of a particular interface in the classes that inherit them. Generally, mixins are self contained. Multiple Inheritance and Mixins differ in semantics. A class which uses multiple inheritance might utilize a mixin as a part of that multiple inheritance. Mixins can be thought of as an interface that is already implemented. We "include" a module in a class definition, its methods are effectively appended, or "mixed in" to the class. Languages like C#, Perl, Python, Ruby take advantage of mixins. Languages like JavaScript do not support mixins but can copy methods from one object to other at run time thereby emulating mixins. Following example shows how to use mixins in a class: module A

  def a1

puts “Method a1”

  end
  def a2

puts “Method a2”

  end

end module B

  def b1

puts “Method b1”

  end
  def b2

puts “Method b2”

  end

end module C

  def c1

puts “Method c1”

  end
  def c2

puts “Method c2”

  end

end class Example include A include B

  def e1
  end

end exp = Example.new // Creating a new object of Example class exp.a1 // Calling a1 method of module A exp.a2 // Calling a2 method of module A exp.b1 // Calling b1 method of module B exp.b2 // Calling b2 method of module B exp.c1 // Calling c1 method of module C exp.c2 // Calling c2 method of module C exp.e1 // Calling e1 method defined inside class Example

Each module A, B and C have two methods a1, a2, b1, b2 and c1, c2 respectively. "include" is the keyword used in Ruby to embed a module in a class. The class Example includes modules A, B and C. Thus, an object of the class Example can access all the methods in A, B and C modules. We can see that Example class shows multiple inheritance or a mixin.


Comparison between C++/Java/Python/Ruby

Multiple Inheritance is supported by several object oriented languages such as C++, Ruby, Perl, Python etc. Let us compare how multiple inheritance is implemented in each of these languages.

C++

class Person { private:

   std::string m_strName;
   int m_nAge;
public:
   Person(std::string strName, int nAge,
       : m_strName(strName), m_nAge(nAge)
   {
   }
   std::string GetName() 
   { 
   	return m_strName; 
   }
   int GetAge() 
   { 
   	return m_nAge; 
   }
   bool IsMale() 
   { 
   	return m_bIsMale; 
   }

}; class Employee { private:

   std::string m_strEmployer;
   double m_dWage;

public:

   Employee(std::string strEmployer, double dWage)
       : m_strEmployer(strEmployer), m_dWage(dWage)
   {
   }
   std::string GetEmployer() 
   { 
    	return m_strEmployer; 
   }
   double GetWage() 
   { 
   	return m_dWage; 
   }

};

// Teacher publicly inherits Person and Employee

class Teacher: public Person, public Employee { private:

    int m_nTeachesGrade;

public:

   Teacher(std::string strName, int nAge, std::string strEmployer, double dWage, int nTeachesGrade)
       : Person(strName, nAge), Employee(strEmployer, dWage), m_nTeachesGrade(nTeachesGrade)
   {
   }

}; In C++, multiple inheritance is achieved by using the colon (:) operator to extend different base classes. In the above example, the "Teacher" class extends the properties of both Person and Employee classes. Thus, an object of "Teacher" class can use the public methods of both the "Person" and "Employee "classes.


Python

Python supports a limited form of multiple inheritance. The parent classes are included within parenthesis following the class name. The following example demonstrates multiple inheritance in Python: class First(object):

   def __init__(self):
       print "first"

class Second(First):

   def __init__(self):
       print "second"

class Third(First):

   def __init__(self):
       print "third"

class Fourth(Second, Third):

   def __init__(self):
       super(Fourth, self).__init__()
       print "that's it"

In Python, parent method does not automatically get called. If methods are overriden, the parent version of method should be called. The keyword "super" is used to call the parent's method. In the above Python example, class "Fourth" inherits classes "Second" and "Third" . The order in which classes are called in the above example is Fourth, Second, Third, First.

Ruby Link to the mixin example Java, another OO language, does not support multiple inheritance. But interfaces in Java can be used to emulate multiple inheritance. Java uses the "extends" keyword to inherit a base class and the keyword "implements" for interfaces. interface I1 {

 abstract void test(int i);

} interface I2 {

 abstract void test(String s);

} public class C1 {

 public void test(float f) {
    float f = this.f;
 }

} public class MultInterfaces extends C1 implements I1, I2 {

 public void test(int i) {
   System.out.println("In MultInterfaces.I1.test");
 }
 public void test(String s) {
   System.out.println("In MultInterfaces.I2.test");
 }
 public static void main(String[] a) {
   MultInterfaces t = new MultInterfaces();
   t.test(42);		// calls the implemented interface I1 method
   t.test("Hello");	// calls the implemented interface I2 method
   t.test(1.42);	// calls the class C1 method
 }

} In Java, a class cannot extend two classes, but can implement more than 1 interfaces. The methods in the interfaces should be implemented by the class using them. In the above example C1 is a parent class, I1 and I2 are interfaces with abstract methods. Objects of the MultInterfaces class can be created only if it implements abstract methods from interfaces I1 and I2.

7. Code examples References: http://www.tutorialspoint.com/ruby/ruby_modules.htm http://www.ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/modules.html http://docs.python.org/tutorial/classes.html#multiple-inheritance http://www.tutorialspoint.com/ruby/ruby_modules.htm