向上造型和向下造型体现了java的多态特性:
向上造型
* 父类的引用指向子类的对象
* 父类类型的变量=子类类型的对象
* 一个对象体现了可以有多种形态
*
* 重点:能点出来什么看类型,最后执行什么看对象(主要针对向上造型)
向下造型:(转换类型)
* instanceof:会返回一个boolean类型的值
* 例如: A instenceof B
* 如果要将A变量强制转换为B类型
* 判断A变量所指对象是否是B的子类或者本类对象
* 如果是,返回true,如果不是,返回false
* 注意:一般在进行向下造型的时候,必须进行instenceof判断,才能
* 进行强转,否则会抛出异常
其实向下造型就只是在向上造型之后为了恢复成对象本身的变量或者它的父变量.以下实例是一个很好的应用
实例1
这是图形类
package Day10;
/**
* 创建一个图形类
*
*/
public class Tuxing {
public int c;
public double area(){
return 0.0;
}
}
这是方形类
Package Day10;
/**
* 方形类
* 假设所有的方形面积计算公式是:
* 周长*周长*周长*0.052
*
*/
public class Fangxing extends Tuxing {
public Fangxing(int c) {
this.c = c;
}
public double area(){
return c*c*c*0.052;
}
}
这是圆形类
package Day10;
/**
* 圆形类
* 假设圆形的面积计算公式:
* 周长*周长*周长*0.0258
*
*
*/
public class Yuanxing extends Tuxing{
public Yuanxing(int c) {
this.c = c;
}
/**
*
* 圆形的面积计算方法
*/
public double area(){
return c*c*c*0.0258;
}
}
package day10;
public class Test {
public static void main(String[] args) {
/**
* 已知三个方形的周长分别是 5,6,7,8,9
* 求出三个方形中最大的面积是多少?
*
* 已知几个圆形的周长分别是 11,12,13,14,15
* 求出圆形中最大的面积是多少?
*
* 圆形和方形中最大的面积?
*
*/
TuXing[] tx=new TuXing[10];
//TuXing tx=new FangXing();
tx[0]=new FangXing(5);
tx[1]=new FangXing(6);
tx[2]=new FangXing(7);
tx[3]=new FangXing(8);
tx[4]=new FangXing(9);
tx[5]=new YuanXing(11);
tx[6]=new YuanXing(12);
tx[7]=new YuanXing(13);
tx[8]=new YuanXing(14);
tx[9]=new YuanXing(15);
//假设数组中的第一个图形的面积为最大值
double max=0;
for(int i=0;i<tx.length;i++){
double d=0;
if(tx[i] instanceof FangXing){
FangXing fx=(FangXing)tx[i];
d=fx.area1();
}
if(tx[i] instanceof YuanXing){
YuanXing fx=(YuanXing)tx[i];
d=fx.area2();
}
//double d=tx[i].area();
if(max<d){
max=d;
}
}
System.out.println("所有图形的最大面积是:"+max);
}
}
这个例子非常好的利用向上造型建立了一个统一的数据类型,然后利用向下造型使得每个循环可以分别调用每个子类里面的方法,是一个生动的范例.
实例2
然后今天还讲了一个俄罗斯方块的题目,就是在一个布满像素的平面上,在指定的地方生成*图案,从而产生自己需要的任何图形.
首先我们定义一个用来表示像素坐标的子类
package Day10;
public class ExCell {
public int x;
public int y;
public ExCell(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
这是主函数
ackage Day10;
public class Test3 {
public static void main(String[] args) {
//产生一个用来表示图形的数组
ExCell[] ce = new ExCell[5];
ce[0]= new ExCell(1,1);
ce[1]= new ExCell(2,2);
ce[2]= new ExCell(3,3);
ce[3]= new ExCell(3,1);
ce[4]= new ExCell(1,3);
print(ce);//调用输出方法
}
public static void print(ExCell[] ce){
for(int i =0;i<10;i++){
for(int j=0;j<20;j++){//两层循环遍历每一个像素点
boolean flag = false;//设置开关,为了防止重复输出,控制输出*的时间
for(int k=0;k<ce.length;k++){
if(i==ce[k].y && j==ce[k].x){
System.out.print("*");
flag = true;//每一个像素点就到数组里去找有没有跟需要的坐标
} //匹配的点,如果有则输出*
}
if(!flag){
System.out.print("-");
}
}
System.out.println();
}
}
}
这个题目其实也可以一个个点的输入,但是每重新输入一种新的图形,都要重写过主函数,十分的麻烦,而这种方法则将输出图形这一个动作集成一个方法,每次只需要输入你想要打印的图形,这个方法就会自动将这个图形打印出来,其实输出图形的过程也可以写进一个个方法里面,主函数里面只需要输入Z或者L就能输出,这个方法体现了程序的可扩展性为变成带来的便利,这能大大提高程序的复用率,减少改变输入需要改变的代码数.
Super()
super关键字
* super:
* -调用父类的成员变量
* -调用父类的实例方法
* -调用父类的构造方法
* 一个类中如果没有手动添加构造方法,则会提供一个默认的无参构造
* 一个类中如果手动添加了构造方法,则不会提供默认的无参构造
* 子类的构造方法中的第一句话一定隐藏了一个super()在调用父类的无参构造
* 在子类的构造方法中手动调用了父类的构造方法(无参或者有参),
* 那么在第一句话则不会默认在调用父类的无参构造了
* 注意:同this一样,我们调用父类的构造方法的时候,一定只能在第一行调用
*
* this()调用构造方法的时候只能出现在第一行,super()也只能写在第一行
* 所以在同一个构造方法中这两个不能同时出现
*