Exercise 42: Is-A, Has-A, Objects, and Classes

An important concept that you have to understand is the difference between a class and an object. The problem is, there is no real "difference" between a class and an object. They are actually the same thing at different points in time. I will demonstrate by a Zen koan:

What is the difference between a fish and a salmon?

Did that question sort of confuse you? Really sit down and think about it for a minute. I mean, a fish and a salmon are different but, wait, they are the same thing, right? A salmon is a kind of fish, so I mean it's not different. But at the same time, a salmon is a particular type of fish so it's actually different from all other fish. That's what makes it a salmon and not a halibut. So a salmon and a fish are the same but different. Weird.

This question is confusing because most people do not think about real things this way, but they intuitively understand them. You do not need to think about the difference between a fish and a salmon because you know how they are related. You know a salmon is a kind of fish and that there are other kinds of fish without having to understand that.

Let's take it one step further. Let's say you have a bucket full of three salmon and because you are a nice person, you have decided to name them Frank, Joe, and Mary. Now, think about this question:

What is the difference between Mary and a salmon?

Again this is a weird question, but it's a bit easier than the fish versus salmon question. You know that Mary is a salmon, so she's not really different. She's just a specific "instance" of a salmon. Joe and Frank are also instances of salmon. What do I mean when I say instance? I mean they were created from some other salmon and now represent a real thing that has salmon-like attributes.

Now for the mind-bending idea: Fish is a class, and Salmon is a class, and Mary is an object. Think about that for a second. Let's break it down slowly and see if you get it.

A fish is a class, meaning it's not a real thing, but rather a word we attach to instances of things with similar attributes. Got fins? Got gills? Lives in water? Alright it's probably a fish.

Someone with a Ph.D. then comes along and says, "No, my young friend, this fish is actually Salmo salar, affectionately known as a salmon." This professor has just clarified the fish further, and made a new class called "Salmon" that has more specific attributes. Longer nose, reddish flesh, big, lives in the ocean or fresh water, tasty? Probably a salmon.

Finally, a cook comes along and tells the Ph.D., "No, you see this Salmon right here, I'll call her Mary, and I'm going to make a tasty fillet out of her with a nice sauce." Now you have this instance of a salmon (which also is an instance of a fish) named Mary turned into something real that is filling your belly. It has become an object.

There you have it: Mary is a kind of salmon that is a kind of fish---object is a class is a class.

How This Looks in Code

This is a weird concept, but to be very honest you only have to worry about it when you make new classes and when you use a class. I will show you two tricks to help you figure out whether something is a class or an object.

First, you need to learn two catch phrases "is-a" and "has-a." You use the phrase is-a when you talk about objects and classes being related to each other by a class relationship. You use has-a when you talk about objects and classes that are related only because they reference each other.

Now, go through this piece of code and replace each ##?? comment with a comment that says whether the next line represents an is-a or a has-a relationship and what that relationship is. In the beginning of the code, I've laid out a few examples, so you just have to write the remaining ones.

Remember, is-a is the relationship between fish and salmon, while has-a is the relationship between salmon and gills.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
## Animal is-a object look at the extra credit
class Animal
end

## ??
class Dog < Animal

  def initialize(name)
    ## ??
    @name = name
  end
end

## ??
class Cat < Animal

  def initialize(name)
    ## ??
    @name = name
  end
end

## ??
class Person

  def initialize(name)
    ## ??
    @name = name

    ## Person has-a pet of some kind
    @pet = nil
  end

  attr_accessor :pet
end

## ??
class Employee < Person

  def initialize(name, salary)
    ## ?? hmm what is this strange magic?
    super(name)
    ## ??
    @salary = salary
  end

end

## ??
class Fish
end

## ??
class Salmon < Fish
end

## ??
class Halibut < Fish
end


## rover is-a Dog
rover = Dog.new("Rover")

## ??
satan = Cat.new("Satan")

## ??
mary = Person.new("Mary")

## ??
mary.pet = satan

## ??
frank = Employee.new("Frank", 120000)

## ??
frank.pet = rover

## ??
flipper = Fish.new()

## ??
crouse = Salmon.new()

## ??
harry = Halibut.new()

Study Drills

  1. Research why Ruby added this strange object class and what that means.
  2. Is it possible to use a class like it's an object?
  3. Fill out the animals, fish, and people in this exercise with functions that make them do things. See what happens when functions are in a "base class" like Animal versus in, say, Dog.
  4. Find other people's code and work out all the is-a and has-a relationships.
  5. Make some new relationships that are arrays and hashes so you can also have "has-many" relationships.
  6. Do you think there's such thing as an "is-many" relationship? Read about "multiple inheritance," then avoid it if you can.

Common Student Questions

What are these ## ?? comments for?
Those are "fill-in-the-blank" comments that you are supposed to fill in with the right "is-a," "has-a" concepts. Read this exercise again and look at the other comments to see what I mean.
What is the point of @pet = nil?
That gives a default to a Person's pet that is nil or "not set to anything."
What does super(name) do?
That's you can run the initialize of the parent class Person before you do what you need inside Employee. Go search for "ruby super" online and read the various advice on it.

Buy DRM-Free

When you buy directly from the author, Zed A. Shaw, you'll get a professional quality PDF and hours of HD Video, all DRM-free and yours to download.

$29.99

Buy Directly From The Author

Or, you can read Learn Ruby the Hard Way for free right here, video lectures not included.