teaching machines

CS 330 Lecture 41 – Multiple Inheritance and Polymorphism

May 13, 2016 by . Filed under cs330, lectures, spring 2016.

Agenda

TODO

Note

Last time we saw that multiple inheritance would be nice, but many languages don’t support it. The reasons for its lack of support are both technical and logical. But several modern languages do provide multiple inheritance—sometimes in creative ways. Ruby, for example, only supports single inheritance, but one can dynamically “mix in” methods from a module into a class. These methods become part of the object’s type. We’ll look at an example making PolycephalousMonsters comparable by the number of heads.

Inheritance is a big part of object-oriented programming, but we must be careful not to be abuse it. It’s primary value is that it imbues a known type on the new types that we create. This means our types can work with code that only knows the inherited types. This is called subtype polymorphism. Public inheritance is not meant to be a vehicle for code reuse—unless you’re willing to accept the supertype interface.

From here we dive into a discussion of subtype polymorphism. There are other types of polymorphism. Ad hoc polymorphism is the name we give to the overloading of methods. One function can be defined for different types. Parametric polymorphism is when we let a function be parameterized by a type. We saw this in Haskell and we see it in generics. Subtype polymorphism is when a piece of code only knows an object’s supertype, but somehow it calls the overridden methods in the subtype. In C++, this dynamic dispatch only happens when a method is virtual. Otherwise, only the compile-time type is considered and we have static dispatch.

How exactly does dynamic dispatch work? Let’s draw some pictures to show what happens with the following hierarchy, borrowed from Stroustrup himself:

/usr/lib/ruby/2.7.0/rubygems/dependency.rb:311:in `to_specs': Could not find 'coderay' (>= 0) among 56 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/.gem/ruby/2.7.0:/var/lib/gems/2.7.0:/usr/lib/ruby/gems/2.7.0:/usr/share/rubygems-integration/2.7.0:/usr/share/rubygems-integration/all:/usr/lib/x86_64-linux-gnu/rubygems-integration/2.7.0:/home/johnch/.gems', execute `gem env` for more information
	from /usr/lib/ruby/2.7.0/rubygems/dependency.rb:323:in `to_spec'
	from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_gem.rb:62:in `gem'
	from ./coderay:24:in `
'

Perry’s Stages of Cognitive Development

We close our class with a little discussion of psychology. In this class, we have looked at a lot of languages and a lot of ideas. As you go from here, you will enter a world that loves to classify everything in two buckets: good and evil. Psychologist William Perry described what stages we pass through as we become an informed human being. I share briefly on these stages to encourage you to strive for something greater than just two buckets.

Duality

I believe actions and beliefs are either right or wrong, and these labels are administered by certain trusted authorities who are always right. I shut my eyes and ears to those labeled wrong; they deserve punishment and misfortune. By the way, C is the language of the gods. Everybody else uses Java.

Multiplicity

We are all authorities, labels of right and wrong are purely arbitrary, and you who listen to others are all a bunch of sheep. I’m going to do what I think is right, and you can do your thing. Anyone that says otherwise is a dualist prig. By the way, I think Ruby is awesome and I’m going to use it for everything. If you want to bow down to Oracle, go ahead. It’s not my problem.

Relativism

Not all authorities are equal and not all are right about everything. Some are charlatans, some are hypocrites, some have reasonable motivations but produce inconsistent outcomes, some are right about X but grossly inexperienced with Y, some are nobler and more consistent than others. By the way, Ruby is great for prototyping, but I do love a statically typed language for building something big. C’s nice and simple, but Java’s standard library is really helpful. Oh, there’s so many choices! How can I learn them all?

Commitment

Based on what I’ve seen of the world, I trust much of what authorities A, B, and C have to say. But I will keep evaluating new ones that come along, and careful weigh what A, B, and C say. My “go-to” language is Ruby, but I’ve been reading about some awesome features in Haskell. I think I’ll try and port them to Ruby.

Code

poly.rb

/usr/lib/ruby/2.7.0/rubygems/dependency.rb:311:in `to_specs': Could not find 'coderay' (>= 0) among 56 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/.gem/ruby/2.7.0:/var/lib/gems/2.7.0:/usr/lib/ruby/gems/2.7.0:/usr/share/rubygems-integration/2.7.0:/usr/share/rubygems-integration/all:/usr/lib/x86_64-linux-gnu/rubygems-integration/2.7.0:/home/johnch/.gems', execute `gem env` for more information
	from /usr/lib/ruby/2.7.0/rubygems/dependency.rb:323:in `to_spec'
	from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_gem.rb:62:in `gem'
	from ./coderay:24:in `
'

Haiku

Masamune vs. Muramasa
Which sword is the best?
The unchecked killer? The checked?
Well, I’ve got two hands