CSC/ECE 517 Fall 2012/ch1 1w17 ir

From Expertiza_Wiki
Revision as of 17:42, 19 September 2012 by Ikjaishw (talk | contribs) (→‎Extending Classes)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Extending Objects


The ‘extend’ feature in computer programming languages allows the programmer to dynamically extend the functionality of an object at run-time, as opposed to extending functionality at compile time. This feature can be found in most Object Oriented Programming (OOP) Languages, some of which are Java, JavaScript, and Ruby. Some OOP languages do not support the 'extend' feature, such as C++.

Introduction

The Object Oriented Programming uses 'objects' for designing applications. These objects consist of an encapsulated set of data fields and methods, and are usually an instance of a class. These objects can communicate with each other through messages (or 'methods') and process data in object oriented programming. But in order to increase an object's functionality, it is necessary to add the features of one object to another. This can be done dynamically at run time, without repeating the code, by extending the features of one class to another. This can be done by the use of the 'extend' keyword. Many Object Oriented Programming support the 'extend' feature.

An object is an entity that serves as a container for data and also controls access to the data. Associated with an object is a set of attributes, which are essentially no more than variables belonging to that object. Also associated with an object is a set of functions that provide an interface to the functionality of the object, called methods. - Hal Fulton<ref>http://rubylearning.com/satishtalim/writing_our_own_class_in_ruby.html</ref>

Most Object Oriented Programming languages (like C++, Java, etc) are static; meaning the object attributes are set at compile time and cannot be changed at run-time. So if one wishes to add on to the features of an object in say, Java, they must do so at compile time. But in dynamically-typed languages like Ruby ,objects can be added onto at run-time. The adding on-to objects can be described as extending the properties of an object to reflect properties of other classes and/or objects.

Languages Using 'extend' Functionality

Java

Object Oriented Programming languages provide mechanisms to implement the object-oriented model. In the real world, the programs are organized around objects and these objects have certain behavior, properties, type, and identity <ref>http://www.tatamcgrawhill.com/html/9780070495432.html</ref>. In OOP based languages, the main aim is to identify the objects and manipulate their relation between each other. Larger applications can be developed with greater flexibility using the OOP. Another important work in OOP is to classify objects into different types according to their properties and behavior.

Objects in Java invoke methods and communicate with each other and perform various tasks such as Input-Output (IO) tasks, running animations and so on. In order to add additional functionality, we can extend these objects through inheritance, so as to enable the objects to perform more functions.

Objects in Java

An object is an instance of a class. Software objects are often used to model the real-world objects that you find in everyday life. Objects are part of a class but are not the same. An object is expressed by the variable and methods within the objects <ref>http://docs.oracle.com/javase/tutorial/java/concepts/</ref>. Again these variables and methods are distinguished from each other as instant variables, instant methods and class variable and class methods. Java considers “Object”<ref>http://www.jvoegele.com/software/langcomp.html</ref> as the ancestor of all classes and provides interfaces to extend or inherit functionality.

Extending Classes

In Java, an object can be created by instantiating a class. Inheritance is one of the most powerful paradigms of Object oriented programming, which allows hierarchical classifications. Inheritance<ref>http://www.javabeginner.com/learn-java/java-inheritance/</ref> is defined as the ability to derive one class from another and inherit its state and behavior. Inheritance allows you to reuse code over and over again in each subclass you create. A class which is inherited is called super class, the class that does that inheriting is called subclass. The subclass can inherit all the instance variables and methods defined in the superclass and and its own functionality. Java uses 'extend' to extend a class (or an interface's) functionality dynamically (even though Java is a statically typed language, the extend functionality enables it to add features at run-time, i.e., dynamically).

A simple example for creating a new object using the 'new' keyword is mentioned below:


Greet today = new Greet();

This statement creates a new Greet object (Greet is a class here). This single statement actually performs three actions: declaration, instantiation, and initialization. Greet today is a variable declaration which declares to the compiler that 'today' is the variable with datatype as Greet.

In the case of single inheritance , a subclass is derived simply from its parent class. To derive a class in java the keyword 'extends' is used. To clearly understand the concept of extending classes using the 'extends' keyword, go through the simple example of single inheritance:


class A {
  int x;
  int y;
  int get(int p, int q){
  x=p; y=q; return(0);
  }
  void Show(){
  System.out.println(x);
  }
}

class B extends A{
  public static void main(String args[]){
  A a = new A();
  a.get(5,6);
  a.Show();
  }
  void display(){
  System.out.println("B");
  }
}

Extending Interfaces

An interface is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of that interface. An interface can extend another interface, similar to the way a class extends another class. Here, the extends keyword is used to extend the interface, and the child interface inherits the methods of the parent interface. In this manner, the interface's functionalities are 'extended' i.e., added to the functionalities of the class.

Here is a simple example to declare an interface:


public interface NameOfInterface
{
   //Any number of final, static fields
   //Any number of abstract method declarations
}

Similar to the way that a class can extend another class, an interface can extend another interface.The 'extends' keyword is used to extend an interface and the child interface inherits the methods of the parent interface. In Java, a class can only extend one parent class. Multiple inheritance is not allowed. Interfaces are not classes but they can extend more than one parent interface.

Here is a simple example of how to extend an interface:


public interface Hello
{
   public void setHi(String name);
   public void setBye(String name);
}

public interface Greet extends Hello
{
   public void greeting();
}

public class JavaExample extends Greet
{
   public void example();
}

In the above example, the Hello interface has two methods, setHi() and setBye(), the Greet interface has one method. The JavaExample class has one method as well. Once an object for the class JavaExample is created, it can access methods setHi(), setBye() and greeting(), due to the extend functionality.

JavaScript

As in Java, objects can be extended at run time to provide more functionality. Classes can be extended using the object.extend() functionality gained by using Prototypes. Although extension in JavaScript may look like extension in Java, they are quite different. The main difference between dynamic extension in Java and JavaScript is that JavaScript uses a Prototype-based extension system, rather than using a Class-based extension system<ref>http://www.bennadel.com/blog/1514-Extending-Classes-In-Object-Oriented-Javascript.htm</ref>.

Prototypes

Prototypes<ref>http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/</ref> are basically objects from which other objects can inherit properties (dynamically)<ref>http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes</ref>. The prototype extend functionality <ref>http://phrogz.net/JS/classes/ExtendingJavaScriptObjectsAndClasses.html#prototype</ref> can be represented by:


Object.extend(Destination, Source)

This copies all properties of the source object to the destination object.

Extending Objects

To extend an object dynamically in JavaScript, we can make use of the above function. For example<ref>http://andrewdupont.net/2009/08/28/deep-extending-objects-in-javascript/</ref>,


var destination = { hello: "user" };
var source = { welcome: "to JavaScript" };

Now, on extending these objects,


Object.extend( destination, source);

we can see the results:


destination.hello; //gives "user"
destination.welcome; //gives "to JavaScript"

source.welcome = "destination is modified";
destination.welcome; //gives "destination is modified"

Ruby

Ruby is a OOP language. It differs from the previous two OOP languages mentioned above in how it interprets what 'object-oriented' means and the different terminologies for the concepts it employs.

In Ruby, everything is an object and all objects are instances of a class. Even classes are instances of class objects. So when there is a class, .new is called to get an instance of the class and when there is an instance, .class is called to obtain its class <ref>http://skilldrick.co.uk/2011/08/understanding-the-ruby-object-model/</ref>. So each class has a superclass and if it doesn't specify any class from which it inherits, then it inherits directly from the Object class.

The picture below depicts the linking between all classes in Ruby. Ruby contains several classes and modules that are available by default. Some of these are Array, Class, Exception, Fixnum, Integer, Numeric, Object, Float, Range, Time, BasicObject, Module and some built-in modules are Kernel, Math, Comparable, Enumerable and so on. All classes are derived from the BasicObject class in Ruby 1.9+. By inheritance rules, all of its methods are available to all the objects.

A class hierarchy in Ruby <ref>http://rubylearning.com/satishtalim/writing_our_own_class_in_ruby.html</ref>

Another way for an object to gain additional methods is by making use of the 'extend' keyword. By using 'extend' with an object, the object gains the methods from a module it is extending.

Example Code Snippet

Here is an example that shows how Object.extend(module) adds the methods defined in a module at the object's level.


 module RubyExample
   def helloWorld
       "Hello user! Welcome to Ruby!"
   end
 end

Now, we can extend this module's functionality (i.e, the Greet method) to any object we instantiate. Below we can see that the module's methods have been mixed in to the object.


 obj = Object.new
 obj.extend(RubyExample)
 obj.helloWorld #=> "Hello user! Welcome to Ruby!"

As mentioned earlier, everything in Ruby is an object. The following confirms this fact:


 >> RubyExample.object_id
 => 45097
 >> RubyExample.class
 => Module
 >> RubyExample.respond_to?(:extend)
 => true

Now this is not the only way to extend object functionality in Ruby. We can also do the same thing by


 RubyExample = Module.new do
   def helloWorld
       "Hello user! Welcome to Ruby!"
   end
 end

 RubyExample.extend(RubyExample)

 RubyExample.helloWorld #=> "Hello user! Welcome to Ruby!"

So, the above alternative method clarifies the fact that RubyWorld is just an instance of the class Module. We can also do the same thing by including the extend() call within the module definition.


 module RubyExample
    extend RubyExample
    def helloWorld
        "Hello user! Welcome to Ruby!"
    end
 end

 RubyExample.helloWorld #=> "Hello user! Welcome to Ruby!"

In Ruby, the keyword 'self' refers to the current or default object itself. So another way of implementing the above is as follows


 module RubyExample
    extend self
    def helloWorld
        "Hello user! Welcome to Ruby!"
    end
 end

 RubyExample.helloWorld #=> "Hello user! Welcome to Ruby!"

Another way to mix Ruby modules into a class is by using the 'include' keyword. For more information, see Extend through Include.

Advantages & Disadvantages

Advantages

In Java, both normal and abstract classes and interfaces can be extended at run-time to provide more functionality. Extending an abstract class allows programmers to create a template of sorts as an abstract class and the classes that extend this class can define these functionalities, which leads to modularity an efficiency.

JavaScript allows methods that are extended via prototypes to be changed simultaneously in all instances. Also, since prototyping enables lesser methods, it decreases page loading time which results in efficiency<ref>http://stackoverflow.com/questions/4508313/advantages-of-using-prototype-vs-defining-methods-straight-in-the-constructor</ref>.

Objects in Ruby are extended for all of their instances and therefore the code stays simple. Also, it is extremely easy to extend any object in ruby, making it one of Ruby's most admired qualities.

Disadvantages

The use of 'extend' in Java is argued to be unnecessarily complicated<ref>http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html</ref>.

In JavaScript, prototypes modify the destination object and leave the source object untouched in almost all scenarios. Supposing the functionality of object A is extended to that of object B, and object B and object A both have a method called 'greet' then object B's method 'greet' will be replaced by that of object A's, leading to a loss of data and method overriding. As this can happen unintentionally, it is a common source of errors.

With Ruby, modules are generally used with classes and hence, the 'include' functionality is made use of more, instead of 'extend'.

Conclusion

In a nutshell, several languages use the extend feature to extend their functionality, but only a few use it dynamically. The dynamic use promotes increased efficiency as well as robustness. Languages like Java, JavaScript and Ruby are all object-oriented and they can use the extend feature to their advantage. The size of code reduces because there is no need to re-use (or re-implement) methods and thus writing applications becomes simpler as well.

See also

Java Interfaces

Interfaces in Java

Interface vs Abstract class

Prototype Object in JavaScript

OOPS JavaScript

JavaScript Prototyping

Extending ruby

Include vs Extend in Ruby

Extending classes in ruby

References

<references />