Wednesday, April 13, 2016

Ruby_Lesson_Object-Oriented Programming I

Introduction to Classes
1.Why Classes?
Ruby is an object-oriented programming language, which means it manipulates programming constructs called objects. (Almost) everything in Ruby is an object! You've been using them all along, so they should be very familiar. Objects have methods, which you've seen before, and attributes, which are just data. For instance, in
"Matz".length
# ==> 4
the "Matz" object is a string with a .length method and a length attribute of 4But what exactly makes "Matz" a string? The fact that it's an instance of the String class. A class is just a way of organizing and producing objects with similar attributes and methods.
2.Class Syntax
A basic class consists only of the class keyword and the name of the class. Check it out:
class NewClass
  # Class magic here
end
Our NewClass has the ability to create new Ruby objects of class NewClass (just like "Hello!" is a String and 4 is a Fixnum). By convention, class names start with a capital letter and use CamelCase instead of relyingonunderscores.
3.Classing It Up
we started our class definition off with a method called initialize. You can think of initialize as the function that "boots up" each object the class creates.
class Person
    def initialize
    end
end

4.What's in a @name?
In Ruby, we use @ before a variable to signify that it's an instance variable. This means that the variable is attached to the instance of the class. For example,
class Car
  def initialize(make, model)
    @make = make
    @model = model
  end
end

kitt = Car.new("Pontiac", "Trans Am")
creates an instance, kitt, of the class Car. kitt has his own @make ("Pontiac") and @model ("Trans Am"). Those variables belong to the kitt instance, which is why t5.Instantiating Your First Object
We can create an instance of a class just by calling .new on the class name, like so:
me = Person.new("Eric")
Classes and Objects
6.Scope it Out
Another important aspect of Ruby classes is scope. The scope of a variable is the context in which it's visible to the program.
It may surprise you to learn that not all variables are accessible to all parts of a Ruby program at all times. When dealing with classes, you can have variables that are available everywhere (global variables), ones that are only available certain methods (local variables), others that are members of a certain class (class variables), and variables that are only available to particular instances of a class (instance variables).
The same goes for methods: some are available everywhere, some are only available to members of a certain class, and still others are only available to particular instance objects.
7.Naming Your Variables
Recall that instance variables begin with an @. This isn't just a Ruby convention—it's part of the syntax! Always start your instance variables with @.
Class variables are like instance variables, but instead of belonging to an instance of a class, they belong to the class itself. Class variables always start with two @s, like so: @@files.
Global variables can be declared in two ways. The first is one that's already familiar to you: you just define the variable outside of any method or class, and voilà! It's global. If you want to make a variable global from inside a method or class, just start it with a $, like so: $matz.
class MyClass
  $my_variable = "Hello!"
end
puts $my_variable

8.For Instance...
Good! A caveat, though: global variables can be changed from anywhere in your program, and they are generally not a very good idea. It's much better to create variables with limited scope that can only be changed from a few places!
For example, instance variables belong to a particular object (or "instance"). Let's get in some practice with instance variables!
Go ahead and add age and profession parameters to the initialize method, then set these equal to instance variables in the body of the method. Use the name/@name example as a guide.
class Person
  def initialize(name,age,profession)
    @name = name
    @age = age
    @profession = profession
  end
end

9.Twice the @, Twice as Classy
We can create class variables by starting a variable name with two @ symbols. Class variables are attached to entire classes, not just instances of classes, like so:
class MyClass
  @@class_variable
end
Because there's only one copy of a class variable shared by all instances of a class, we can use them to pull off some cool Ruby tricks. For example, we can use a class variable to keep track of the number of instances of that class we've created.
class Person
  @@people_count = 0
  def initialize(name)
    @name = name
    @@people_count += 1
  end
  def self.number_of_instances
    return @@people_count
  end
end

matz = Person.new("Yukihiro")
dhh = Person.new("David")

puts "Number of Person instances: #{Person.number_of_instances}"

Inheritance
11.Watch Your Step
Inheritance is the process by which one class takes on the attributes and methods of another, and it's used to express an is-a relationship. For example, a cartoon fox is a cartoon mammal, so a CartoonFox class could inherit from a CartoonMammal class. However, a Wizard is not an Elf , so it shouldn't inherit from the Elf class (even if they have a lot of magical attributes and methods in common). Instead, both Wizard and Elf could ultimately inherit from the same MagicalBeing class.
12.Inheritance Syntax
In Ruby, inheritance works like this:
class DerivedClass < BaseClass
  # Some stuff!
end
where the derived class is the new class you're making and the base class is the class from which that new class inherits. You can read "<" as "inherits from."
13.Override!
Sometimes you'll want one class that inherits from another to not only take on the methods and attributes of its parent, but to override one or more of them.
For instance, you might have an Email class that inherits from Message. Both classes might have a send method that sends them, but the e-mail version may have to identify valid e-mail addresses and use a bunch of e-mail protocols that Message knows nothing about. Rather than add a send_email method to your derived class and inherit a send method you'll never use, you can instead just explicitly create a send method in the Email class and have it do all the email-sending work.
This new version of send will override (that is, replace) the inherited version for any object that is an instance of Email.
class Creature
  def initialize(name)
    @name = name
  end
 
  def fight
    return "Punch to the chops!"
  end
end

class Dragon < Creature
    def fight
        return "Breathes fire!"
    end
end

14.When Good isn't Good Enough
On the flip side, sometimes you'll be working with a derived class (or subclass) and realize that you've overwritten a method or attribute defined in that class' base class (also called a parent or superclass) that you actually need. Have no fear! You can directly access the attributes or methods of a superclass with Ruby's built-in super keyword.
The syntax looks like this:
class DerivedClass < Base
  def some_method
    super(optional args)
      # Some stuff
    end
  end
end
When you call super from inside a method, that tells Ruby to look in the superclass of the current class and find a method with the same name as the one from which super is called. If it finds it, Ruby will use the superclass' version of the method.
Replace the return statement inside Dragon's definition of fight with the keyword super. (No need to pass any arguments to super, since Creature's fight method doesn't take any.)
class Dragon < Creature
    def fight
        puts "Instead of breathing fire..."
        super
    end
end

15.There Can Be Only One!
Any given Ruby class can have only one superclass. Some languages allow a class to have more than one parent, which is a model called multiple inheritance. This can get really ugly really fast, which is why Ruby disallows it.
However, there are instances where you want to incorporate data or behavior from several classes into a single class, and Ruby allows this through the use of mixins.if you want to end a Ruby statement without going to a new line, you can just type a semicolon. This means you can write something like
class Monkey
end
on just one line: class Monkey; end. This is a time saver when you're writing something very short, like an empty class or method definition.
class Dragon < Creature; end
class Dragon < Person; end

See how we're trying to get Dragon to inherit from Creature and Person? We'll get a superclass mismatch for class Dragon error if we try this.
Project
2.Create Your Class
Create a class called Computer and give it an initialize method that takes no parameters. The body of initialize should be empty.
class Computer
    def initialize
    end
end

3.Fancify Your Initialize Method
Update initialize to take two parameters, username and password. In the body of initialize, set the instance variables @username and @password (respectively) to these parameters.
In your initialize method, you'll also want to create a @files instance variable and set this to an empty hash. This is so we can keep track of our files later!
class Computer
    def initialize(username,password)
        @username = username
        @password = password
        @files = {}
    end
end

4.Have a Little Class
Add a class variable called @@users to your Computer class. Set it equal to an empty hash.
In your initialize method, set @@users[username] = password so that your @@users hash keeps usernames as keys with each username's password as the associated value.
class Computer
    @@users = {}
    def initialize(username,password)
        @username = username
        @password = password
        @files = {}
        @@users[username] = password
    end  
end

5.Getting More Creative

  1. Inside your Computer class, define a method called create with a single parameter, filename.
  2. Inside create, declare a variable called time and set it equal to the current time (using Time.now).
  3. Next, inside create, add a new key/value pair to the @files hash. Use the filename key to store the value time.
  4. For the final step in create, please puts a message telling the user that a new file was created. Feel free to put in any information you like; the one we used in exercise 1 printed the filename, the username, and the time.
class Computer
    @@users = {}
    def initialize(username,password)
        @username = username
        @password = password
        @files = {}
        @@users[username] = password
    end  
    def create(filename)
        time = Time.now
        @files[filename] = time
        puts "A new file was created,filename: #{filename},username: #{username}, time: #{time}"
    end
end

6.Who're the Users?
Because @@users is a class variable, we'll use a class method to grab it. Most of the methods you've seen so far are instance methods—they work on a particular instance/object, such as "matz" or "blixy". A class method belongs to the class itself, and for that reason it's prefixed with the class name, like so:
class Machine
  def Machine.hello
    puts "Hello from the machine!"
  end
end
  1. Add a new class method to your Computer class called Computer.get_users. It should have no parameters.
  2. Your new Computer.get_users method should return the @@users class variable.
class Computer
    @@users = {}
    def initialize(username,password)
        @username = username
        @password = password
        @files = {}
        @@users[username] = password
    end  
    def create(filename)
        time = Time.now
        @files[filename] = time
        puts "A new file was created"
    end
    def Computer.get_users
        return @@users
    end
end

7.Instantiation Nation
my_computer = Computer.new("Becky","123456")









1 comment :

  1. I think you're missing an at symbol (@) on the username

    class Computer

    @@users = {}

    def initialize(username, password)
    @username = username
    @password = password
    @files = {}
    @@users[username] = password
    end

    def create(filename)
    time = Time.now
    @files[filename] = time
    puts "#{filename}, was created by, #{@username} at #{time}"
    end
    end

    ReplyDelete