CSC/ECE 517 Fall 2012/ch1b 1w56 ms: Difference between revisions

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


==Inheritance==
==Inheritance==
One of the most important concepts in object-oriented programming is that of inheritance. Inheritance allows us to define a class in terms of another class, which makes it easier to create and maintain an application. The newly formed class is called the derived class or the sub-class, the class that we derive from is called base class or the super-class.
Although, inheritance provides an opportunity to reuse the code functionality and hasten  implementation time, Ruby does not support Multiple level of inheritances. However, this functionality can be implemented using another feature called [http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html mixins]. A mixin is like a specialized implementation of multiple inheritance in which only the interface portion is inherited.
The syntax for extending a class is by adding a “<” character and the name of the superclass to the class statement.
Example :<br>
----
<FONT FACE="courier">class Account<br>
  # constructor used when Account.new(...) called<br>
  def initialize(starting_balance=0) # optional argument<br>
    @balance = starting_balance<br>
  end<br>
end<br>


Content
class SharedAccount < Account<br>
# adding another instance variable “common_fund” and an instance method “share”<br>
 
def share(common=0) # optional argument<br>
    @common_fund = common<br>
    print "Total Balance : #{@balance + @common_fund}"<br>
  end<br>
end<br>
a = SharedAccount.new 10<br>
a.share(20)<br>
<br><br>
Output : Total Balance : 30<br>
 
</FONT>
----
The above, will make use of both base class and derived class instance variables.


==Instance Variables and Accessor Methods==
==Instance Variables and Accessor Methods==

Revision as of 01:24, 4 October 2012

Introduction

What is Object Oriented Programming?

Wikipedia defines Object-oriented programming (OOP) as a programming paradigm that uses objects and their interactions to design applications and computer programs. The primary programming concepts in OOP are:

  • Abstraction - hiding all but the necessary data about an object in order to reduce complexity and increase efficiency.
  • Polymorphism - characteristic of being able to assign a different meaning to a particular function or "operator" in different contexts.
  • Encapsulation - hide the implementation details of a class from other objects.
  • Inheritance - form new classes using existing class definitions.

Ruby is pure object-oriented language! i.e to Ruby, everything appears as an object. Every value in Ruby is an object, even the most primitive things: strings, numbers and even true and false. Ruby is so true to being object oriented that even a class is an object that is an instance of the ‘C’lass class. In object-oriented code, we model concepts from the real world. During this modeling process you’ll different items to be represented. In Ruby, classes are defined to represent each of these items. Objects, which are instances of a class are nothing but different kinds of that item in terms of Ruby.

Now let’s look at some basic object oriented concepts in Ruby.

Object

Objects are basic building blocks of a Ruby OOP program. Every basic item, when being represented, can be given its own properties and actions. Object-oriented programming calls properties by the name instance variables , whose names starts with @, and actions are known as methods. A class is a template for an object, and an object is an instance of the class. Objects are created by calling a constructor, a special method associated with a class. The constructor in Ruby is called initialize. Constructors do not return any values. Constructors can be parameterized too, to contain values that initialize the instance method. This is also called the initialize method. For example,

Example:


class Account

 # constructor used when Account.new(...) called
def initialize(starting_balance=0) # optional argument
@balance = starting_balance
end

end


account1 = Account.new 10


Here the constructor, when invoked will create an object of type ‘Account’ represented by the name account1nitialize the instance variable balance to 10. Each object gets its own set of instance variables. Different objects communicate together through methods. Each object can receive messages, send messages and process data.

Class

A class can be defined as a blueprint for a data type. It defines the state and behaviour of the class, that is, what an object of the class will consist of and what operations can be performed on such an object. A class represents the real world entity.

A class definition starts with the keyword class followed by the class name and is delimited with an end. For example we defined the BankAccount class using the keyword class as follows:

Example:


class BankAccount

 attr_accessor :name, :balance
def deposit(amt)
@balance+=amt
end

end


The class BankAccount, contains instance variables(defined later) name and balance that defines the state of an object of the class and a method deposit that defines the behavior. Here, the name (BankAccount) must begin with a capital letter. By convention, names that contain more than one word run together with each word capitalized and no separating characters (CamelCase).

Inheritance

One of the most important concepts in object-oriented programming is that of inheritance. Inheritance allows us to define a class in terms of another class, which makes it easier to create and maintain an application. The newly formed class is called the derived class or the sub-class, the class that we derive from is called base class or the super-class. Although, inheritance provides an opportunity to reuse the code functionality and hasten implementation time, Ruby does not support Multiple level of inheritances. However, this functionality can be implemented using another feature called mixins. A mixin is like a specialized implementation of multiple inheritance in which only the interface portion is inherited. The syntax for extending a class is by adding a “<” character and the name of the superclass to the class statement. Example :


class Account

 # constructor used when Account.new(...) called
def initialize(starting_balance=0) # optional argument
@balance = starting_balance
end

end

class SharedAccount < Account

# adding another instance variable “common_fund” and an instance method “share”

def share(common=0) # optional argument

   @common_fund = common
print "Total Balance : #{@balance + @common_fund}"
end

end
a = SharedAccount.new 10
a.share(20)


Output : Total Balance : 30


The above, will make use of both base class and derived class instance variables.

Instance Variables and Accessor Methods

Instance Variables

An instance variable begins with the symbol “@” in Ruby. It is different from a local variable because its scope is confined to the object to which self refers. Instance variables are invisible outside of the object. The only way we can access them or observer them is by writing methods to get or set the value of them. Instance variables have the value “nil” until they are initialized. Instance variables do not need to be declared. In fact we can also access instance variables without declaring or initializing it, this will not raise an exception. However a warning will be issued if we run it using the –w switch. Every instance variable is dynamically appended to an object in the first assignment.
Example:


@balance -> instance variable


Accessor Methods

As stated previously, we cannot access instance variables from anywhere outside an object. Hence we need to define methods to access them. They are generally called as getter and setter methods. The getter method is used to return the value of the instance variable. It would be defined as:

Example:


def balance
@balance
end


The setter method is used to set the value of the instance variable. Setter methods always end with the “=” sign. It would be defined as:
Example:


def balance= (bal)
@balance = bal
end


Instead of writing getter and setter methods for each class, we can use the attr_accessor function. The attr_accessor is a method call which uses metaprogramming to generate the getter and setter methods dynamically at run time.

Example:


attr_accessor :balance


This is equivalent to



def balance
@balance
end

def balance= (bal)
@balance = bal
end


We can also generate getter and setter methods for more than one instance variable.



attr_accessor :balance, :new_balance


We can also use attr_reader if we only want to generate the getter function. Similarly we can use the method call attr_writer for generating just the setter function.

Instance Methods

Instance methods work with instances of the class. So in order to use instance methods we have to create an instance.

Example:


def deposit
@balance += amount
end


You can include the definition of an instance method within the class like this: Example:


Class SavingsAccount < Account
def deposit
@balance += amount
end
end


Or you can also define it later. Since Ruby is a dynamic programming language we are allowed to reopen a class and add methods to it. For instance to add the deposit method after closing the class:


Class SavingsAccount < Account
end
SAcc = SavingsAccount.new
def SAcc.deposit
@balance += amount
end


The save and update methods used in Rails are actually instance methods.

There are two types of methods in Ruby: Safe methods and destructive methods. They are called as safe and destructive depending on whether they modify the input parameters passed to them. The destructive methods end with the “!” symbol, so that they can warn the programmer when he is writing the code. “<<” is another example of a destructive method.

Class Variables and Class Methods

Class Variables

A class variable begins with the symbol “@@” in Ruby. Once we define a class variable it is set for the class and all of its subclasses.
Example:


@@bank_name = “MyBank.com”


We need to add a getter method to access the class variable from outside the class. This would look like:


def self.bank_name
@@bank_name
end


puts SavingsAccount.bank_name => “MyBank.com”


Class Methods

Class methods are equivalent to static methods in Java. Class methods only exist in the class that defined them. So we cannot call a class method with an instance variable, because the class method does not exist in the instance variable. There are multiple ways of defining class methods.

  • def SavingsAccount.bank_name
  • def self.bank_name
  • class << self
    def bank_name

In Method 1 we use the class name followed by a dot followed by the class method name. In Method 2 we use the keyword self. In Ruby self gives you access to the current object, when defined within a class it refers to the current class. Method 2 is frequently used to define a class method. In the third method we are actually building an anonymous class for the current object (referred by self) using the << notation. We are doing exactly what we did in Method 2, it is uncommon to see the use of Method 3.

References

http://www.rubyfleebie.com/understanding-class-methods-in-ruby/
http://stackoverflow.com/questions/2084490/ruby-class-variables
http://railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/
http://railsguru.org/2010/04/quick-ruby-tutorials-3-class-and-instance-methods/
http://www.rubyist.net/~slagell/ruby/instancevars.html
http://www.rubyist.net/~slagell/ruby/accessors.html