This morning: “Surprise! Want to conduct a job interview?” I’ve been here a little over 3 months, but um, sure! “Great. He’s in the conference room right now.” Wow, we move quick.
So, without much time to gather my thoughts for good tech-y interview questions, I printed out the resume, and I winged it. In the middle of the interview, I flipped over his resume, and scribbled out short-hand C# like this:
class A {
public A() {
Console.WriteLine(“in A”);
}
}
class B : A {
public B() {
Console.WriteLine(“in B”);
}
}
class C : B {
public C() {
Console.WriteLine(“in C”);
}
}
new C();
I asked, “What does this print out?” You know, see if he knows which order constructor inheritance goes in. I wanted to hear, “in A, in B, in C”, but not “in C, in B, in A”.
I forget exactly what the candidate’s answer was, but it stirred up a bit of discussion, because the three of us interviewing him disagreed on the answer: one of us said it would only print “in C,” because you need to stick : base()
on the B and C constructors for the inheritance to work; I agreed with the third interviewer, who said it would print “in A, in B, in C”, because constructor inheritance is automatic (with no-arg constructors). We fudged around it, laughed a bit, and the interview moved on. (Update: here’s the answer.)
Back at my desk, I had to try it out. I didn’t want to bother with a whole Visual Studio .sln and all that nonsense, so I tried it in Ruby:
class A
def initialize
puts “in A”
end
end
class B < A
def initialize
puts "in B"
end
end
class C < B
def initialize
puts "in C"
end
end
C.new
[/sourcecode]
And the output is..."in C"! Huh? That can't be right...I was sure constructors were inherited automatically! Then I realized, of course! I’m working in Ruby, and you have to explicitly call superclass methods, constructors included:
class A
def initialize
super # <- call the superclass' constructor
puts "in A"
end
end
class B < A
def initialize
super # <- call the superclass' constructor
puts "in B"
end
end
class C < B
def initialize
super # <- call the superclass' constructor
puts "in C"
end
end
C.new
[/sourcecode]
Stupid Ruby! Did I find a case where C# actually works nicer than Ruby? But then I realized, this also means Ruby lets you change the order of the constructor inheritance: you can go bottom-up, if you want, or even stranger:
[sourcecode language='ruby']
class A
def initialize
super
puts "in A"
end
end
class B < A
def initialize
super
puts "in B"
end
end
class C < B
def initialize
puts "in C"
super # <- call up the chain AFTER we're done
end
end
C.new
[/sourcecode]
That one prints out "in C, in A, in B". The nice thing? No rule to memorize, and more control. The down-side? More to type. But given how compact Ruby already is, I think the added control is worth it here. What do you think?
(Update: I eventually did fire up Visual Studio, and the code above printed “in A, in B, in C”, without me typing out : base()
. C# inherits constructors automatically, and the superclass constructors run before subclass constructors.)