CSC/ECE 517 Fall 2011/ch4 4c ap: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
Line 84: Line 84:


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 "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 Apple
ApplePie has-a Cinnamon
ApplePie has-a Cinnamon
The relationship can be a composition but not inheritance.
The relationship can be a 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.
"Is-a" relationship does not exist. The thumb rule to check if inheritance is allowed is to verify the "is-a" relationship.

Revision as of 16:28, 17 October 2011

Modules and Mixins

Regular Expressions

Modules and Mixins

Mixins

Comparable

Composing Modules

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 direct Multiple Inheritance. But, Mutiple Inheritance can be achieved in Ruby through Modules. Modules simulate multiple inheritance in Ruby.

 Example - Taggable string

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. Another example

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. Another example

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 mortgages, one might factor out FIXED_RATE and ADJUSTABLE mortgages. Another example

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 them. 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. Another example

Disadvantages of Multiple Inheritance

Programmers use multiple inheritance to increase re-usability 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()). In Java, some people call this situation the "Deadly Diamond of Death". This is illustrated by the figure below:

figure

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.

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.

4. Implementation difficulties

Multiple inheritance can result it 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.

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 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.

Extending Specific Objects

See Also

References

External Links