Skip to content

Instantly share code, notes, and snippets.

@appleios
Forked from JoseJRVazquez/Advanced Classes
Last active August 29, 2015 14:18
Show Gist options
  • Save appleios/f2e5d9a3b4f268767718 to your computer and use it in GitHub Desktop.
Save appleios/f2e5d9a3b4f268767718 to your computer and use it in GitHub Desktop.

Ok, so Inheritance

its not just for young white dudes waiting for their grandparents to fucking keel over at 82.

In ruby, Inheritance allows one class to inherit from another class attributes and behaviors (methods) that it didnt have before. The inheriter, much like a young white male, is the child class. The class that it inherits from, rather than being his old money grandparents, is the Parent Class. The lesson says Inheritance is designated with a < symbol, for example:

class Daughter < Father
end

wow, quick right. So for that, the daughter is getting methods from the father. Simple right. But lets go deeper and see how fucked up this can really get for those of us in the cheap seats.

class Father
  def say_hello
    "hello"
  end
end

class Daughter < Father
end

d = Daughter.new
d.say_hello
#=> "hello"

So the little pain in the ass, the daughter, now gets to use her dads shit. Its like the dad goes on vacation and leaves the keys to his kid, and she can now go hog fucking wild. Or letting her take the Amex to the mall before prom. Damage is done

In the forumla above, the daughter inherited from the father, and now the instance is called daughter. His shit, is now her shit.

SO, the lesson says parent classes should be as generic as possible. They should be able to describe a broad swath of things, such as the word Dog. The lesson says the following:

"The purpose of this class will be to define the general attributes and behavior that all dogs share, regardless of breed. Attributes like having a name, four legs, two eyes and a tail are shared amongst all dog breeds. Behavior like eating, sleeping and barking are also shared amongst all dog breeds."

check out the code

class Dog
  def initialize(name)
    @name = name
  end
end

now lets make a method in it

class Dog
  def initialize(name)
    @name = name
  end

  def speak
    "Ruff, my name is #{ @name }."
  end
end

So, now, we are supposed to imagine that many different child classes will be built from this. So for example,we created the Dog class with the idea that we will create child classes for different breeds of dogs. In this respect, the name attribute declared in the Dog class will make sense when applied to any child class. Simply put, our program is assuming that all dogs, regardless of breed, should have names.

class Mutt < Dog
end

Because Mutt inherits from the Dog class, i dont have to specify the initialize method, unless I want to set more attributes that are not generic enough to initialize in Dog. We can access the name attribute from the parent class by using the SUPER method:

class Mutt < Dog
  def initialize(name)
    super
  end
end

The Super method, lets us use a method of the same name in the parent class. Again, this is DRY rearing its head as an overall principle again. I can see the value. Check this shit out

> 2.0.0-p451 :022 > class Mutt < Dog
> 2.0.0-p451 :023?>     def initialize(name)
> 2.0.0-p451 :024?>         super
> 2.0.0-p451 :025?>       end
> 2.0.0-p451 :026?>   end
> => nil 
> 2.0.0-p451 :027 > charlotte = Mutt.new("Charlotte")
> => #<Mutt:0x0000010192dc70 @name="Charlotte"> 
> 2.0.0-p451 :028 > charlotte.speak
> => "Ruff, my name is Charlotte." 
> 2.0.0-p451 :029 > 

So not charlotee can use the dogs method to her own benefit. Saving some typing steps.

Extensive inheritance: So, you can have child, and even grandchild classes. An example they give is the ANIMAL Class in the following example:

class Animal
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def eat(other)
    puts "#{@name} ate #{other.name}! #{self.noise}"
  end
end

Here comes a child class, Humans

class Human < Animal
  attr_accessor :catchphrase

  def initialize(name, catchphrase)
    super(name)
    @catchphrase = catchphrase
  end

  def noise
    @catchphrase
  end
end

here comes the test

> 2.0.0-p451 :052 > a = Human.new("Adam", "Right on!")
> => #<Human:0x000001010913f0 @name="Adam", @catchphrase="Right on!"> 
> 2.0.0-p451 :053 > b = Animal.new("Chicken")
> => #<Animal:0x0000010107bd98 @name="Chicken"> 
> 2.0.0-p451 :054 > a.eat(b)
> Adam ate Chicken! Right on!
> => nil 

Now taking it a step further

> 2.0.0-p451 :055 > class Englishman < Human
> 2.0.0-p451 :056?>     def initialize(name = "Mick Jagger")
> 2.0.0-p451 :057?>         super(name, "I can't get no....")
> 2.0.0-p451 :058?>       end
> 2.0.0-p451 :059?>   end
>  => nil 
> 2.0.0-p451 :060 > a = Human.new("Adam", "Right on!")
>  => #<Human:0x000001019545c8 @name="Adam", @catchphrase="Right on!"> 
> 2.0.0-p451 :061 > mick = Englishman.new
> => #<Englishman:0x0000010193d8f0 @name="Mick Jagger", @catchphrase="I can't get no...."> 
> 2.0.0-p451 :062 > mick.eat(a)
> Mick Jagger ate Adam! I can't get no....
> => nil 
> 2.0.0-p451 :063 > 

So taking this a step further with siblings

class Dog < Animal
  attr_accessor :excitment_level

  def initialize(name, excitment_level)
    super(name)
    @excitment_level = excitment_level
  end

  def noise
    "woof" * @excitment_level
  end
end

Testing the new Dog class:

d = Dog.new("Eight", 3)
d.eat(d)
#=> "Eight ate Eight! woofwoofwoof

All of this leads us to Modules

Modules let us group together certain methods. Useful when a group of methods generaically apply to class that are usually unrelated. The lesson uses the following example

module Location
  attr_accessor :x, :y

  def set_location(x,y)
    @x, @y = x, y
  end

  def distance_to(other)
    dx = self.x - other.x
    dy = self.y - other.y
    Math.sqrt(dx ** 2 + dy ** 2)
  end

  def wurr_u_at
    puts "#{self.name} is at (#{x},#{y})"
  end
end

This lets us drop inthe Include statement again, as follows:

class Person
  attr_accessor :name

  include Location
end

class City
  include Location
end

So now we can all share this wonderful location formula. Share and share alike. Thats the shit. So in the PErson and City modules, both use location. Its called a MIXIN. Im going to try this, and here is what came out

2.0.0-p451 :001 > module Location
2.0.0-p451 :002?>     attr_accessor :x, :y
2.0.0-p451 :003?>   
2.0.0-p451 :004 >       def set_location(x,y)
2.0.0-p451 :005?>         @x, @y = x, y
2.0.0-p451 :006?>       end
2.0.0-p451 :007?>   
2.0.0-p451 :008 >       def distance_to(other)
2.0.0-p451 :009?>         dx = self.x - other.x
2.0.0-p451 :010?>         dy = self.y - other.y
2.0.0-p451 :011?>         Math.sqrt(dx ** 2 + dy ** 2)
2.0.0-p451 :012?>       end
2.0.0-p451 :013?>   
2.0.0-p451 :014 >       def wurr_u_at
2.0.0-p451 :015?>         puts "#{self.name} is at (#{x},#{y})"
2.0.0-p451 :016?>       end
2.0.0-p451 :017?>   end
 => nil 
2.0.0-p451 :018 > class Person
2.0.0-p451 :019?>     attr_accessor :name
2.0.0-p451 :020?>   
2.0.0-p451 :021 >       include Location
2.0.0-p451 :022?>   end
 => Person 
2.0.0-p451 :023 > 
2.0.0-p451 :024 >   class City
2.0.0-p451 :025?>     include Location
2.0.0-p451 :026?>   end
 => City 
2.0.0-p451 :027 > a = Person.new
 => #<Person:0x00000103089478> 
2.0.0-p451 :028 > a.name = "Georgia"
 => "Georgia" 
2.0.0-p451 :029 > a.set_location(2,3)
 => [2, 3] 
2.0.0-p451 :030 > b = City.new
 => #<City:0x00000101108130> 
2.0.0-p451 :031 > b.x = 5
 => 5 
2.0.0-p451 :032 > b.y = 7
 => 7 
2.0.0-p451 :033 > a.distance_to(b)
 => 5.0 
2.0.0-p451 :034 > a.wurr_u_at
Georgia is at (2,3)
 => nil 
2.0.0-p451 :035 > b.wurr_u_at
NoMethodError: undefined method `name' for #<City:0x00000101108130 @x=5, @y=7>
	from (irb):15:in `wurr_u_at'
	from (irb):35
	from /usr/local/rvm/rubies/ruby-2.0.0-p451/bin/irb:12:in `<main>'
2.0.0-p451 :036 > 

A module can also be used to namespace groups of methods. Namespacing allows you to use the same name for multiple methods and classes, if the need should arise. This is similar to storing similarly named files in different directories.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment