有一个重要的概念你需要弄明白,那就是Class
「类」和Object
「对象」的区别。问题在于,class 和 object 并没有真正的不同。它们其实是同样的东西,只是在不同的时间名字不同罢了。我用禅语来解释一下吧:
鱼(Fish)和鲑鱼(Salmon)有什么区别?
这个问题有没有让你有点晕呢?说真的,坐下来想一分钟。我的意思是说,鱼和鲑鱼是不一样,不过它们其实也是一样的是不是?泥鳅是鱼的一种,所以说没什么不同,不过泥鳅又有些特别,它和别的种类的鱼的确不一样,比如鲑鱼和比目鱼就不一样。所以鲑鱼和鱼既相同又不同。怪了。
这个问题让人晕的原因是大部分人不会这样去思考问题,其实每个人都懂这一点,你无须去思考鱼和鲑鱼的区别,因为你知道它们之间的关系。你知道鲑鱼是鱼的一种,而且鱼还有别的种类,根本就没必要去思考这类问题。
让我们更进一步,假设你有一只水桶,里边有三条鲑鱼。假设你的好人卡多到没地方用,于是你给它们分别取名叫Frank,Joe,Mary。现在想想这个问题:
Mary 和鲑鱼有什么区别?
这个问题一样的奇怪,但比起鱼和鲑鱼的问题来还好点。你知道 Mary是一条鲑鱼,所以他并没什么不同,他只是鲑鱼的一个「实例(instance)」。Joe 和Frank 一样也是鲑鱼的实例。我的意思是说,它们是由鲑鱼创建出来的,而且代表着和鲑鱼一样的属性。
所以我们的思维方式是(你可能会有点不习惯):鱼是一个「类(class)」,鲑鱼是一个「类(class)」,而 Mary 是一个「对象(object)」。仔细想想,然后我再一点一点慢慢解释给你。
鱼是一个「类」,表示它不是一个真正的东西,而是一个用来描述具有同类属性的实例的概括性词汇。你有鳍?你有鳔?你住在水里?好吧那你就是一条鱼。
后来一个博士路过,看到你的水桶,于是告诉你:「小伙子,你这些鱼是鲑鱼。」 专家一出,真相即现。并且专家还定义了一个新的叫做「鲑鱼」的「类」,而这个「类」又有它特定的属性。长鼻子?红肉?体型大?住在海里或是干净新鲜的 水里?吃起来味道不错?那你就是一条鲑鱼。
最后一个厨师过来了,他跟博士说:「非也非也,你看到的是鲑鱼,我看到的是Mary,而且我要把 Mary 淋上美味酱料做一道小菜。 」于是你就有了一只叫做Mary 的鲑鱼的「实例(instance)」(鲑鱼也是鱼的一个「实例」),并且你使用了它(把它塞到你的胃里了),这样它就是一「对象 (object)」。
这会你应该了解了:Mary 是鲑鱼的成员,而鲑鱼又是鱼的成员。这里的关系式:对象属于某个类,而某个类又属于另一个类。
写完后的代码是什么样子
这个概念有点诡异,不过实话说,你只要在建立和使用class的时候操心一下就可以了。我来给你两个区分Class
和Object
的小技巧。
首先针对类和对象,你需要学会两个说法,「is-a(是啥)」和「has-a(有啥)」。「是啥」要用在谈论「两者以类的关系互相关联」的时候,而「有啥」要用在「两者无共同点,仅是互为参照」的时候。
接下来,通读这段代码,将每一个注解为##??
的位置标明他是「is-a」还是「has-a」的关系,并讲明白这个关系是什么。在代码的开始我还举了几个例子,所以你只要写剩下的就可以了。
记住,「是啥」指的是鱼和鲑鱼的关系,而「有啥」指的是鲑鱼和烤肉架的关系。
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 88 89 90 91 92 93 |
<span class="c">## Animal is-a object (yes, sort of confusing) look at the extra credit</span> class Animal end <span class="c">## ??</span> class Dog < Animal def initialize<span class="o">(</span>name<span class="o">)</span> <span class="c">## ??</span> @name <span class="o">=</span> name end end <span class="c">## ??</span> class Cat < Animal def initialize<span class="o">(</span>name<span class="o">)</span> <span class="c">## ??</span> @name <span class="o">=</span> name end end <span class="c">## ??</span> class Person attr_accessor :pet def initialize<span class="o">(</span>name<span class="o">)</span> <span class="c">## ??</span> @name <span class="o">=</span> name <span class="c">## Person has-a pet of some kind</span> @pet <span class="o">=</span> nil end end <span class="c">## ??</span> class Employee < Person def initialize<span class="o">(</span>name, salary<span class="o">)</span> <span class="c">## ?? hmm what is this strange magic?</span> super<span class="o">(</span>name<span class="o">)</span> <span class="c">## ??</span> @salary <span class="o">=</span> salary end end <span class="c">## ??</span> class Fish end <span class="c">## ??</span> class Salmon < Fish end <span class="c">## ??</span> class Halibut < Fish end <span class="c">## rover is-a Dog</span> <span class="nv">rover</span> <span class="o">=</span> Dog.new<span class="o">(</span><span class="s2">"Rover"</span><span class="o">)</span> <span class="c">## ??</span> <span class="nv">satan</span> <span class="o">=</span> Cat.new<span class="o">(</span><span class="s2">"Satan"</span><span class="o">)</span> <span class="c">## ??</span> <span class="nv">mary</span> <span class="o">=</span> Person.new<span class="o">(</span><span class="s2">"Mary"</span><span class="o">)</span> <span class="c">## ??</span> mary.pet <span class="o">=</span> satan <span class="c">## ??</span> <span class="nv">frank</span> <span class="o">=</span> Employee.new<span class="o">(</span><span class="s2">"Frank"</span>, 120000<span class="o">)</span> <span class="c">## ??</span> frank.pet <span class="o">=</span> rover <span class="c">## ??</span> <span class="nv">flipper</span> <span class="o">=</span> Fish.new <span class="c">## ??</span> <span class="nv">crouse</span> <span class="o">=</span> Salmon.new <span class="c">## ??</span> <span class="nv">harry</span> <span class="o">=</span> Halibut.new |
