Give another name for subtype polymorphism.
Inclusion polymorphism.
Explain subtype polymorphism.
Enables an object of a subclass to be used wherever a value of its superclass is expected. Also when object is sent a message, chooses method to invoke based on runtime type.
Define polymorphic references.
Allows a single reference to refer to objects of different types during execution.
obj.foo(). What is the object called in terms of dynamic binding?
The receiving object
pet.speak is a method invocation but what would be a more accurate term and why?
message send, we send the pet object message speak and we do not know which method will be invoked it decides that.
If we (a) want default behavior with each subclass redefining this behavior slightly or (b) we want any subclasses to be able to respond to some message without default behavior, what should we use?
(a) Overriding
(b) Abstract Methods
Explain template method.
Is a skeletal method in the superclass (trait) that invokes several other methods which are not implemented in the superclass. The subclasses inherit it and must implement each of the abstract methods it invokes.
When should we use template methods?
When there is a related method for the classes.
No suitable default implementation exists.
T or F. The template method and any methods in it already fully implemented in the superclass should be declared final, we don’t want to let people change the implementation.
True
T or F. The flow of control in a Template method stays in the superclass.
False, it jumps between classes, which can make them hard to understand.
What is a hook method?
Is one that has an implementation in the superclass but is intended to be overridden.
Is a part of the template method where there is variability and you may change if you wish. No obligation like other abstract methods.
T or F. Traits can be instantiated unlike abstract classes.
False, neither can.
Define trait.
A trait is like a class, it can have a constructor, methods and implementations but it cannot be instantiated, it must be extended like an abstract class and it forces implementation of abstract methods in contains.
What is a concrete method?
A fully implemented method.
What is the name of the problem caused by multiple inheritance?
The Diamond Problem.
Explain how the Diamond Problem works.
Occurs where a class inherits from two or more parent classes who themselves share a common superclass. Issue is it is not clear if class D should inherit once or twice from A.
A / \ B C \/ D
How would you practically demonstrate diamond problem? (code)
class c1(val someValue)
class c2 extends c1
class c3 extends c1
class c4 extends c2, c3
And come up with a case where it makes sense for c4 to have someValue twice and another where it should have someValue only once.
Compiler cannot decide between the two options as it doesn’t have domain knowledge.
What is the solution to the diamond problem?
Extending multiple traits instead (+ precise linearisation to enforce ordering)
Distinguish between thin and rich interfaces.
Thin interface provides just enough for client to use the class. Not easy to use and code duplicate across clients.
Rich interface provides lots of methods. More work for implementor and hard to find relevant methods.
Syntax for using the Ordered trait.
class X(val myVal: Int) extends Ordered[X]
def compare(other: X) = myVal - other.myVal
Must define compare method!!!
Define stackable traits.
Multiple trait implementations can be mixed into a class and combined in a linear order. Where each trait can augment or modify behavior before delegating to next trait in stack using super.
Explain how stackable traits works.
e.g. 2nd Trait in Extends List:
trait SomeTrait extends SomeBaseClass
abstract override def someMethod(i : Int) = super.someMethod(i + 1)
Syntax for calling stackable traits using variables. What is var foo?
val foo = new default with SomeTrait with SomeOtherTrait
foo is an instance of an anonymous class.
val myQueue = new BasicIntQueue
with Doubling with Incrementing. Explain how myQueue.put(1) would execute.
Search for put starts in BasicIntQueue, the one there is overridden by Doubling which is in turn overridden by incrementing.
So Incrementing.put is called first, it calls super.put which binds to Doubling.put which in turn calls super.put which binds to BasicIntQueue.put.