CSC/ECE 517 Fall 2011/ch3 4b ms: Difference between revisions
No edit summary |
(→Ruby:) |
||
Line 19: | Line 19: | ||
==== Ruby: ==== | ==== Ruby: ==== | ||
Ruby is dynamically typed and highly object-oriented, much more than Java and Python. In Ruby, it is said that “everything is an object”. Every value happens to be an object in Ruby. You may call methods on a string, an integer just like you call on any object in Java. | Ruby is dynamically typed and highly object-oriented, much more than Java and Python. In Ruby, it is said that “everything is an object”. Every value happens to be an object in Ruby. You may call methods on a string, an integer just like you call on any object in Java. For ex, | ||
(2.1143).size.times{puts “Hello!”} | |||
This example will display “Hello!” six times on your IRB as the size of the parameter "2.1143" is 6. | |||
== Comparison of object Oriented Languages == | == Comparison of object Oriented Languages == |
Revision as of 17:49, 18 October 2011
Lecture 5: Object Oriented Programming in Ruby
This wiki tries to cover the Object Oriented concepts in ruby.
Object oriented languages: An Overview
C++:
C++ is a statically typed, multi-paradigm programming language. It supports some features of object-oriented languages like encapsulation, polymorphism and inheritance. It provides access control by specifiers public, private and protected and also allows “friend” classes. C++ allows multiple inheritance which is eliminated in most other programming languages as it allows a class to inherit from more than one base class which results in an ambiguity effect.
Java:
Java is classified as a statically typed, hybrid object oriented language. Although it provides information hiding, inheritance and polymorphism, it has a few basic types incorporated that are not objects and some of the built-in operators are provided by basic arithmetic and not as messages to objects. [link]. For these reasons, it is not considered to be a “pure” object-oriented language.
Java provides access control and supports private, public and protected access. It also allows to create packages to create and maintain namespaces. Java is designed not to provide multiple inheritance to avoid problems faced in C++. However, it presents a single-rooted hierarchy where “Object” is the ancestor of all classes (seen in Ruby too) and provides interfaces to extend/inherit functionality.
Python:
Python is a dynamically typed, interpreted, object oriented language. It is argued that Python is not completely object oriented as it does not provide access control.
Ruby:
Ruby is dynamically typed and highly object-oriented, much more than Java and Python. In Ruby, it is said that “everything is an object”. Every value happens to be an object in Ruby. You may call methods on a string, an integer just like you call on any object in Java. For ex,
(2.1143).size.times{puts “Hello!”}
This example will display “Hello!” six times on your IRB as the size of the parameter "2.1143" is 6.
Comparison of object Oriented Languages
Language | Ruby | Java | C# | C++ | Python | SmallTalk | Perl |
---|---|---|---|---|---|---|---|
Object Orientation | Pure | Hybrid | Hybrid | Hybrid/Multi-Paradigm | Hybrid | Pure | Add-on/Hybrid |
Static/Dynamic Typing | Dynamic | Static | Static | Static | Dynamic | Dynamic | Dynamic |
Generic Classes | N/A | No | No | Yes | N/A | N/A | N/A |
Inheritance | Single Class/Multiple Mixins | Single Class/Multiple Interface | Single Class/Multiple Interface | Multiple | Multiple | Single | Multiple |
Feature Renaming | Yes | No | No | No | No | No | NO |
Method Overloading | No | Yes | Yes | Yes | No | No | No |
Operator Overloading | Yes | No | Yes | Yes | Yes | Yes | Yes |
Class Variables or methods | Yes | Yes | Yes | Yes | No | Yes | No |
Access Control | Public, Protected, Private | Public, Protected, Package, Private | Public, Protected, Private, Internal, Protected Internal | Public, Protected, Private, Friends | Name Mangling | Protected Data, Public Methods | None |
Ruby : Purely Object Oriented
Ruby is considered to be a purely Object oriented Language, as everything in it is considered to be an object. Unlike Java, even primitives such as characters, punctuation, numbers and strings are treated as objects in Ruby. Ruby was designed to facilitate the enforcement of Object Oriented Methods. Ruby is a Dynamically Typed Language.
Object oriented Concepts in ruby:
Ruby is a singly rooted Object Oriented Programming language which has all its classes having the same superclass which is the class Object.
Classes:
A class is used to define a blueprint of a data type. It does not contain any data, but it specifies what kind of variables and methods an object of the class will have. A class in Ruby is defined using the keyword class followed by the classname. The variables and methods are defined within the class definition and the class definition terminates with the end keyword.
For ex: class Rectangle
def initialize(w,l) @width, @length = w, l end
end Here, the initialize method is used to set the values of the instance variables (@width and @length. The instance variables are the properties of the objects created of this class type. These instance variables can be accessed within the class using an @. These variables can be accessed from outside the class using the accessor methods which are defined inside the class.
In the following case printLength and printWidth are public methods used to access the instance variables from outside the class. These are called accessor methods. Similarly, to
class Rectangle # constructor method def initialize(w,l) @width, @length = w, l end
# accessor methods def printWidth @width end
def printLength @length end
# setter methods def setWidth=(value) @width = value end def setHeight=(value) @height = value end
end
# create an object rectagle = Rectangle.new(10, 20)
# use accessor methods x = rectangle.printWidth() y = rectangle.printLength()
puts "Width of the Rectangle is : #{x}" puts "Length of the Rectangle is : #{y}"
Class Methods and Class Variables:
A class variable is shared between all instances of the class. The value of the class variable remains the same for all the objects of the class. A class variable is accessed within the class using two @ signs at the beginning of the variable name. The class variables must be initialized within the class.
The class methods are defined using def self.methodname() and ends with an end delimiter. These methods are called using the class name itself, for example: classname.methodname
Attributes and accessor methods:
Every class in Ruby defines a set of attributes for its objects. Ruby provides accessor methods (famously known as getter-setter methods in Java) to access these variables. Ruby provides three kinds of accessor methods:
Class Car
attr_accessor : name, company attr_reader: price attr_writer: color
end
attr_accessor creates a setter and getter method. The attr_reader method creates only the getter method. This is required in case of attributes that are not to be modified by other programs but their value may be viewed. The attr_writer creates the setter method. In case of Java, the setter and getter methods need to be written in 3 lines of code each whereas in Ruby, the methods are written just by specifying the type of accessor, which have already been coded using Metaprogramming.[link]
Access Control:=
Just like any other o-o programming language, Ruby allows to exercise control over the attributes and methods of a class. Ruby provides 3 levels of protection at instance methods level. Public: In this level objects from outside the class can call the method. All methods except initialize are public by default. Private: These methods can be call only by the objects of the same class. Initialize methods are private by default. Protected: These methods can be called either by objects of the same class or of the class derived from this class.
The methods are given access levels using the following syntax. Private :method1, :method2
Abstract methods
Ruby is a dynamically typed language and does not provide abstract classes as in Java or C++. It instead provides modules that can be included within any class. The reason why Ruby does not provide abstract classes is because of the idea that it only matters if two objects can perform a function, they don’t necessarily have to be inherited from the same class. This paradigm is provided by modules, where the method of a module can be redefined as required by a class that includes it.
Also, if required the technique of abstract class can be simulated by something like this:
Class Vehicle def drive raise NotImplementedError.new("Method not implemented") end end
The subclasses that inherit from the above class will have to redefine the method “drive” as required.
Duck Typing in Ruby
Ruby provides unbounded polymorphism as a dynamically typed language through the concept of “Duck-typing”. “Duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface” [link]. This concept is explained by the famous definition as “When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.” This essentially means that in languages like Ruby, it is only checked if an object can implement a function and the type of the object is not taken into consideration. It can be explained better with the help of the following example
class Lion def roar puts “The Lion roars when hungry” end end
class Person def roar puts “The man roared in fury and anger” end end
def quality lion lion.roar end
def start leo = Lion.new jack = Person.new quality leo quality jack end
start
In the above example, leo is an object of class “Lion” and the “roar” method defined in its class is invoked. jack is an object of class “Person” and the corresponding method defined in the Person class is called for him. Although in the real world, both objects are not of the same type, Ruby allows unbounded polymorphism as both of them implement a particular aspect.
Thus, the check for an invoked method is done at run-time in dynamically typed languages and the method defined on that object type is called. If the method is undefined, a “NoMethodError” exception is raised.