import java.util.Vector; class Pt extends Object { float x; float y; Pt(float _x, float _y) { x = _x; y = _y; } } class Pt3D extends Pt { float z; Pt3D(float _x, float _y, float _z) { super(_x,_y); z = _z; } } /*class C extends Object { void f(Pt3D p1, Pt p2) {} void f(Pt p1, Pt3D p2) {} void g(Pt3D p1, Pt3D p2) { f(p1,p2); } }*/ interface I { Object apply(Object o); } class Compose implements I { I f; I g; public Object apply(Object o) { return g.apply(f.apply(o)); } Compose(I _f, I _g) {f = _f; g = _g;} } class A1 implements I { public Object apply(Object o) { return apply((Pt) o); } public Pt3D apply(Pt p) { return new Pt3D(p.x, p.y, 0);} } class A2 implements I { public Object apply(Object o) { return apply((Pt3D) o); } public Pt apply(Pt3D p) { return new Pt(p.x, p.y); } } class A3 { void f() { I copyPoint = new Compose(new A1(), new A2()); Pt p = (Pt)copyPoint.apply(new Pt(3,4)); } } class B1 { void f() { Vector v = new Vector(10); char [] a = new char[1]; a[0] = 'h'; v.add(0,a); char c = ((char[])v.elementAt(0))[0]; // more interestingly, this is why Java encourages iterators instead of // passing in objects with apply methods (see above) } } interface J { int apply(Object env, String str); } class B2 { int f(Object env, J g) { String s1 = "hi"; String s2 = "mom"; return g.apply(env,s1) + g.apply(env,s2); } } class B3 implements J { public int apply(Object env, String str) { String otherString = (String) env; int len1 = otherString.length(); int len2 = str.length(); return len1 > len2 ? len1 : len2; } void f() { B2 b = new B2(); b.f("glob",this); b.f(new Object(), this); } }