我读了这样一个GUI程序:
import java.awt.*;
public class TestPaint{
public static void main(String[] args){
new PaintFrame().launchFrame();
}
}
class PaintFrame extends Frame{
public void launchFrame(){
setBounds(200,200,640,480);
setVisible(true);
}
public void paint(Graphics g){
Color c = g.getColor();
g.setColor(Color.red);
g.fillOval(50,50,50,50);
g.fillRect(80,80,40,40);
g.setColor(c);
}
}
这是一个可以在内存中运行的程序,这里是结果, [抱歉,我没有足够的声誉来发布图片,但它可以运行]
当我读取APIfile时,我发现fillOval()方法在Graphics类中定义如下:
public abstract void fillOval(int x,
int y,
int width,
int height)
为什么我可以在程序中直接使用抽象fillOval()?此外,在哪里可以找到此程序中fillOval()的具体实现?
答案 0 :(得分:2)
为了实例化任何抽象类,必须在某处具体实现。这是被调用的实现。
与界面一样,合同也是指定的。
因此,您可以安全地调用该方法(因为合同必须得到任何实现的尊重)。
答案 1 :(得分:0)
由于抽象方法不能在非抽象类Graphics
中,因此类应该是抽象的。您无法创建抽象类的实例,并且fillOval()
方法都不是静态的。所以无法调用该方法。
现在了解事实。抽象类中的抽象方法应该由扩展抽象类的第一个具体类来实现。因此,您必须创建一个extends Graphics
的非抽象类,并在其中提供fillOval()
的实现。然后在程序中创建并实例化它并调用它。
答案 2 :(得分:0)
传递给该方法的Graphics
对象实际上是该类的子类(因为从SomeClass
"延伸的任何对象都是-a" {{1}这个具体的子类实现了SomeClass
方法的逻辑。
例如:
fillOval
如果要查看对象的实际类型,可以使用abstract class A {
abstract void doStuff();
}
class B extends A {
void doStuff() {
System.out.println("B::doStuff()");
}
}
class Main {
public static void main(String[] args) {
A obj = new B();
obj.doStuff(); // prints B::doStuff()
}
}
,在这种情况下评估为g.getClass().getCanonicalName()
。可以找到源代码here。
答案 3 :(得分:0)
最后,我知道调用fillOval()函数存在多态性,传递给函数的Graphics g是一个子类引用。