Question:
I posted this question to Java newsgroups, but the response from experts avoids the real issue.
Simple applet:
import java.applet.*; import java.awt.*; public class FirstApplet extends Applet { public void paint(Graphics g) { g.drawString(“Hello world”,25,50); } }
Graphics
class is abstract, i.e. cannot be instantiated. drawString
is a method of Graphics
and is also abstract, so has no body, so cannot be called. The source code states that a variable g
of type Graphics
is passed to method paint
, but it does not say that Graphics
is subclassed and instantiated, which is what must happen for g
to have something to point at.
That is, there is a semantic gap; something is happening beyond what the code actually tells us!
Can you explain that there is not a semantic gap here? That Java is indeed an unambiguous language? The line “paint(Graphics g)
” only says that a variable of type Graphics
is passed, which should result in a compile error.
Answer:
Maybe I’ll have to join the legions of “experts” who have misunderstood your question, but I’ll give it a shot anyway.
It seems to me that the actual graphics
context associated with your applet will be an instance of some class that extends the abstract Graphics
class, and will provide an implementation for drawString()
:
Since Java methods are bound dynamically, like C++ virtual functions, the actualclass AppletGraphics extends Graphics { public void drawString(…) {…} // etc. }
drawString()
method called won’t be determined until runtime. Since specialization is implicit, g
will automatically be cast as an instance of AppletGraphics
, and the call to drawString(…)
will be bound to Applet.drawString(…)
. In other words, the call to drawString()
expands into the call:
(AppletGraphics)g.drawString(…);
at runtime.