//: c10:Shapes.java
// From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002
// www.BruceEckel.com. See copyright notice in CopyRight.txt.
class Shape {
static void g() { System.out.println(" g() in Shape"); }
void draw() { System.out.println(this + ".draw()"); }
}
class Circle extends Shape {
static void g() { System.out.println(" g() in Circle"); }
public String toString() { return "Circle"; }
}
class Square extends Shape {
static void g() { System.out.println(" g() in Square"); }
public String toString() { return "Square"; }
}
public class Shapes {
public void go(Shape s) {
System.out.println(s);
}
public void descendre(Circle c) {
System.out.println(c);
}
public static void main(String[] args) {
Object[] shapeList = {
new Circle(),
new Square(),
};
// 例子1. 子类Circle覆盖父类Shape的静态函数,但父类指针会调用父类的静态函数。
System.out.println("==================ex1==================");
Shape s1 = (Circle)shapeList[0];
s1.g();
// 但普通成员函数仍然会调用Circle的
System.out.println(s1);
// 例子2. 当参数要求是Shape,却可以直接传子类Circle的指针而不必做转换,可编译直接通过!
// 推论:如果参数是Object,那么可以不做转换传递任何参数。
System.out.println("==================ex2==================");
Shapes sh = new Shapes();
Circle c1 = new Circle();
sh.go(c1);
System.out.println();
// 例子3. 正确:父类指针指向子类,在传递父类指针给函数参数时,可正确调用子类的函数
System.out.println("==================ex3==================");
Shape sp = new Circle();
sh.go(sp);
// 错误:sh.descendre(sp); 此时sp仍是Shape类型(即使实际上是Circle),但仍然无法编译通过。
// sh.descendre(sp);
// 正确:做了转换就可以了
Circle cc = (Circle)sp;
sh.descendre(cc);
// 正确:同时也可直接调用父类指针指向的子类函数。
System.out.println(sp);
// 错误:但是如果go函数的参数是Square的话(与Circle平起平坐),此时传递Circle参数编译无法通过。
// 例子4,统一使用Shape类型进行动态联编
System.out.println("==================for==================");
for(int i = 0; i < shapeList.length; i++) {
Shape tmp = (Shape)shapeList[i];
tmp.g();
System.out.println(tmp);
}
// String str=args[0];
// System.out.println(args[1].toString());
}
} ///:~