CSC/ECE 517 Fall 2012/ch1 1w17 ir
Extending Objects
The ‘extend’ feature in computer programming languages allow 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 Object Oriented Programming (OOP) Languages.
Introduction
The programming paradigm OOP 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 OOP oriented languages 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>
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 [2]. 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.<ref>http://www.roseindia.net/java/beginners/oop-in-java.shtml</ref>
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 [3]. 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 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.
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.
Extending Interfaces
An interface is a collection of abstract methods [4]. A class implements an interface, thereby inheriting the abstract methods of the interface. An interface can extend another interface, similarly to the way that a class can extend another class. The extends keyword is used to extend an interface, and the child interface inherits the methods of the parent interface.
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[5].
Prototypes
Prototypes are basically objects from which other objects can inherit properties (dynamically)[6]. The prototype extend functionality [7] 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[8],
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 [9]. 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.
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[10].
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[11].
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 methods and thus writing applications becomes simpler as well.
See also
References
<references />