Skip to content

Instantly share code, notes, and snippets.

@leahgarrett
Last active April 1, 2019 01:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leahgarrett/9d3f3342f46759e29a183a81792ed957 to your computer and use it in GitHub Desktop.
Save leahgarrett/9d3f3342f46759e29a183a81792ed957 to your computer and use it in GitHub Desktop.
Inheritance vs Composition

Inheritance vs Composition

OOP (object oriented programming) inheritance. You can think of inheritance as a ‘is a’ relationship. A car is a automobile. A lion is a cat. A man is a human. These are all relationships that can be defined by using inheritance. The child class has all the features of the parent.

In code it would look like this:

class Automobile

end

class Car < Automobile

end

Ok but what if we want to use functionality from another class that doesn’t exactly fit into that ‘is a’ relationship? Well it probably fits into a different type of relationship know as a ‘has a’ relationship, which uses a concept know as composition. Composition is just using another class within a class. Lets say that we have a class that defines different ways automobiles can move. Well a movement is not a car so inheritance won’t work. But a car has a movement so we can use composition! Lets see what this looks like in code:

class Movement
    def drive
        puts "We are driving"
    end
end

class Automobile

end

class Car < Automobile
    def initialize
        @movement = Movement.new
    end

    def drive
        @movement.drive
    end
end

Composition example from previous challenge

class AussieDate
    def initialize(year, month, day, hour = 0, min = 0)
        @date = DateTime.new(year, month, day, hour, min)
    end
    # methods omitted
end

Challenges

  • morning challenge and sample solution below (product_list_test.rb and product_list.rb)
  • challenge auction_list_test.rb below
  • Implement a class that uses AussieDate
  • Implement a class that uses the Auction Item List class

Beast

Implement the exercises in:
Inheritance Versus Composition

require 'minitest/autorun'
require 'faker'
require_relative 'auction_item'
require_relative 'auction_item_list'
class ProductListTest < MiniTest::Test
def setup
@paragraph = Faker::Lorem.paragraph
@auction_item_list = AuctionItemList.new ([
AuctionItem.new({
:name => 'Antique',
:reserve_price => '250',
:sold_price => 0.0,
:description => @paragraph,
}),
AuctionItem.new({
:name => 'Vintage Sample',
:reserve_price => '150',
:sold_price => '200',
:description => @paragraph,
}),
AuctionItem.new({
:name => 'Olde Iteme',
:reserve_price => '670',
:sold_price => 0.0,
:description => @paragraph,
}),
AuctionItem.new({
:name => 'Olde Antique',
:reserve_price => '95',
:sold_price => '199',
:description => @paragraph,
}),
AuctionItem.new({
:name => 'Antique Sample',
:reserve_price => '395',
:sold_price => '399',
:description => @paragraph,
}),
])
end
def test_find_by_name
found_item = @auction_item_list.find_by_name('Olde Antique')
assert_equal 95, found_item.reserve_price
end
def test_sort_by_sold_price
end
def test_highest_sold_price
end
def test_select_sold_items
end
def test_select_unsold_items
end
def test_select_items_by_sold_price_range
end
end
# Use the AuctionItem class from a previous challenge
# (example solution here: https://gist.github.com/leahgarrett/06fe68fabd3589f7bdd6ea477b8ac8d1)
# Write a class called AuctionItemList
# Make the test, test_find_by_name, pass
# Use the existing test and the tests in the morning challenge as a guide to writing tests
# Write one test at a time. Make it pass before going on to the next test
# Beast
# Use faker to add at least 10 more test cases
# Use ranges to with the test data to ensure you still know the case being tested. eg: smallest price
# Use the seed to re-run the same test
require_relative 'product'
class ProductList
def initialize(products)
@products = products
end
def find_by_name(name)
@products.find { |product| product.name == name }
end
def sort_by_price
@products.sort { |x, y| x.price <=> y.price }
end
def highest_price
sort_by_price.last
end
end
require 'minitest/autorun'
require_relative 'product'
require_relative 'product_list'
class ProductListTest < MiniTest::Test
def setup
@product_list = ProductList.new([
Product.new({
:name => 'Widgit',
:price => '10.99'
}),
Product.new({
:name => 'Gadget',
:price => '9.99'
}),
Product.new({
:name => 'Sample',
:price => '19.99'
}),
])
end
def test_find_by_name
found_product = @product_list.find_by_name('Gadget')
assert_equal 9.99, found_product.price
assert_equal 'Gadget', found_product.name
end
def test_sort_by_price
sorted_products = @product_list.sort_by_price
assert_equal 'Gadget', sorted_products.first.name
assert_equal 'Sample', sorted_products.last.name
end
def test_highest_price
product = @product_list.highest_price
assert_equal 'Sample', product.name
end
end
# Use the Product class from a previous challenge
# (example solution here: https://gist.github.com/leahgarrett/06fe68fabd3589f7bdd6ea477b8ac8d1)
# Write a class called ProductList and make all the tests pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment