Skip to content

Instantly share code, notes, and snippets.

@luizfonseca
Last active January 19, 2017 16:55
Show Gist options
  • Save luizfonseca/7257786d1aecd1baff11ee5c276f7f72 to your computer and use it in GitHub Desktop.
Save luizfonseca/7257786d1aecd1baff11ee5c276f7f72 to your computer and use it in GitHub Desktop.
OOP Advanced => Inheritance, Class Methods and Self
# Our Chef class that receives a Restaurant as a parameter
class Chef
attr_reader :name
def initialize(name, restaurant)
@name = name
@restaurant = restaurant # Can be any Restaurant
end
end
# Always require the class you need on the specific Child class
require_relative "restaurant"
# We create another type of Restaurant:
# A fast food one, and it inherits (takes from another class)
# from Restaurant.
# Which means: every behavior and state (methods and instance variables)
# will be present here, on this class, as what we call CHILD class.
class FastfoodRestaurant < Restaurant
def initialize(name, capacity, category, preparation_time)
# Call for parent
# Call for parents initialize method,
# You can see that RESTAURANT.initialize accepts only 3 arguments, but Fastfood accepts 4
# As this is specific to this Class, you can just store the value as you would normally do
# Specific behavior for specific class is something that you will see a lot on Ruby/Rails
super(name, capacity, category)
@preparation_time = preparation_time
end
# You can work with 2 approaches
# You can overwrite the method like we did
# or you can operate on SUPER (if the super method returns something you
# can check for its value
def open?
Time.now.hour >= 11 && Time.now.hour <= 18
end
# Overriding open? doesnt affect closed? response, it now belongs to this class
# So if you change open? here, closed? will return the appropriate value
end
require_relative "restaurant"
require_relative "chef"
# You can see that we are requiring a new file here: Chef
# Which contains a new Chef class that is specific to GastronomicRestaurant
# RESTAURANT (the parent) doesnt know about it, and dont have behaviors for it,
# this is what specific class logic looks like. You write behavior for this class only.
# SELF = always refers to this class, and when you create a new instance (using .new),
# self refers to that instance at that moment
class GastronomicRestaurant < Restaurant
attr_reader :chef
# Again, 5 parameters
def initialize(name, capacity, category, stars, chef_name)
# Calling RESTAURANT initialize method
super(name, capacity, category)
# We have this specific instance variables for GastronomicRestaurant
# So we Just need to store them properly, as you would do on initialize
@stars = stars
# SELF refers to this class (Gastronomic Restaurant) -
# SELF refers to the instance when creating a new instance of Gastronomic (GastronomicRestaurant.new)
@chef = Chef.new(chef_name, self)
end
# We dont have any specific behavior, no need to override
end
# This is the parent class of all other
# Restaurant types
# Usually a parent is a class that is a "Concept" (it's abstract)
# And has some common behavior
class Restaurant
attr_reader :name
attr_accessor :capacity
def initialize(name, capacity, category)
# instance variables
@name = name
@capacity = capacity
@category = category
@clients = []
end
# Class method, you can access them
# By using self.
# You cannot use a instance method or variable inside of the class method,
# because they dont exist yet (As for this method, it exists when you use Restaurant)
def self.categories
%w{Japanese Thai Brazilian}
end
def reserve(client_name)
@clients << client_name
end
def print_clients
@clients.each do |client|
puts "- #{client}"
end
end
def print_categories
Restaurant.categories
end
# These lines are
# equal to writing attr_reader / attr_writter
# def name
# return @name
# end
# def capacity
# return @capacity
# end
# def capacity=(capacity)
# @capacity = capacity
# end
# Instance methods
# Method to check if the restaurant is open, using just Time.now.hour
def open?
Time.now.hour >= 9 && Time.now.hour <= 18
end
def closed?
!open?
end
end
#require_relative "restaurant"
require_relative "fastfood_restaurant"
require_relative "gastronomic_restaurant"
require_relative "mc_donalds"
bibi = Restaurant.new("Bibi Sucos", 15, "Juices")
# p "#{bibi.name} supports #{bibi.capacity}"
# p "#{bibi.name} is #{bibi.open? ? 'open' : 'closed'}"
# # bibi.capacity = 25
# # bibi.reserve("Anthony")
# # bibi.print_clients
# p bibi.open?
# p bibi.print_categories
# mc_donalds = FastfoodRestaurant.new("Mc Donalds", 50, "Burgers", 4)
# # p mc_donalds
# # p mc_donalds.open?
# p Restaurant.categories
# # p mc_donalds.print_categories
# # p mc_donalds.closed?
# # p mc_donalds.reserve("Madalena")
# # p mc_donalds.print_clients
# This instance has all Restaurant methods, except the Class method.
manekineko = GastronomicRestaurant.new("Manekineko", 35, "Japanese", 1, "Jamie Oliver")
# p manekineko
# p manekineko.open?
# p manekineko.reserve("Alexia")
# p manekineko
# jamie = Chef.new "Jamie Oliver", manekineko
# p jamie.restaurant
# # new_mc = McDonalds.new("Mc Donalds", 50, "Burgers", 4)
# # p new_mc
# p new_mc.open?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment