mport java.awt.*;
import java.applet.*;
public class TuXing extends Applet{
public void paint(Graphics g){
int x[]={30,30,70,50,90,100};
int y[]={150,175,190,220,250,280};
g.drawString("图形绘制",20,20);
g.drawLine(60,60,100,60);
g.drawRect(70,80,20,30);
g.fillRect(200,100,20,30);
g.drawRoundRect(120,50,130,50,30,30);
g.fillRoundRect(240,150,70,40,20,20);
g.fill3DRect(250,60,70,40,true);
g.drawOval(90,100,50,40);
g.fillOval(270,200,50,40);
g.drawArc(170,80,60,50,0,120);
g.fillArc(280,250,60,50,30,120);
g.drawPolygon(x,y,6);
}
}
这里有很多abstract方法,
请告诉我是这些抽象方法由谁实现的?为什么可以直接用?
解析1:抽象方法肯定不可用类名调用,因为他一定不是编译绑定的,一定是运行绑定的
抽象方法是这个抽象类的可实例的子类实例化的实例,他的抽象方法已经在创建实例时动态绑定了,
所以才可以调用
解析2:对于静态方法,是编译时候决定方法的入口,所有的实例调用的是同样的代码。静态变量类似
非静态方法,在实例创建时决定方法的入口,不同的实例可能有不同的入口,这个就体现出继承和多态
解析3:public void paint(Graphics g)里面的g并非java.awt.Graphics,而是Graphics context(图形语义环境)---我也不是很清楚这是什么东东,但api里说到它的功能是允许应用程序在component上画东西显示在不同的设备上的一种环境。所有component的Graphics context都继承了java.awt.Graphics,applet也是Component的子类,故这里的Graphics g 就不是abstract Graphics了,而是Applet的Graphics context
解析4:对这个g带过来的参数是Graphics 的子类的实例 ,他已经实现了这个类的方法,
不信你把这个g的类名打印出来,再把这个类找到,反编译后看看他是不是实现了这些方法的
其实JDK中还有很多类,你从来都只用了抽象类,其实在JDK原代码中封装了一个内部类作为缺省实现。
这个就象的数据库连接一样,你使用的数据库连接,是获得的一个接口实现的类的名字,你根本不需要
知道是有谁实现的。
解析5:public void paint(Graphics g) { }
这里只是说,paint()方法接收一个Graphics类型的参数,而实际传入的肯定是Graphics子类的一个实例了!因为Graphics是抽象类,不可能直接生成实例。只不过,在这里,这个Graphics子类的实例是由JVM传入的。
下面的代码可以解释:
abstract class Humanbeing {
abstract void eat(Object food);
}
class Chinese extends Humanbeing {
public void eat(Object food) { System.out.println("Eating in Chinese style"); }
}
class Westerner extends Humanbeing {
public void eat(Object food) { System.out.println("Eating in western style"); }
}
public class Dinner {
Object food = new Object();
public void giveFood(Humanbeing h) {
h.eat(this.food);
}
public static void main(String[] args) {
Dinner d = new Dinner();
d.giveFood(new Chinese());
d.giveFood(new Westerner());
}
}
Humanbeing 是一个抽象类,但在Food的giveFood()方法中,可以调用Humanbeing的eat方法,因为传入giveFood()方法的,一定是Humanbeing的一个子类的实例。