Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!news.glorb.com!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail From: Lew Newsgroups: comp.lang.java.programmer Subject: Re: Java casting question Date: Wed, 12 Oct 2011 19:05:40 -0700 (PDT) Organization: http://groups.google.com Lines: 94 Message-ID: <4447573.399.1318471540216.JavaMail.geo-discussion-forums@prfp13> References: <4e964097$0$281$14726298@news.sunsite.dk> Reply-To: comp.lang.java.programmer@googlegroups.com NNTP-Posting-Host: 67.218.107.62 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1318471996 6332 127.0.0.1 (13 Oct 2011 02:13:16 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 13 Oct 2011 02:13:16 +0000 (UTC) In-Reply-To: <4e964097$0$281$14726298@news.sunsite.dk> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=67.218.107.62; posting-account=CP-lKQoAAAAGtB5diOuGlDQk0jIwmH0T User-Agent: G2/1.0 X-Google-Web-Client: true Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:8750 Arne Vajh=F8j wrote: > Chad wrote: >> Given the following... >> >> class X { >> void f1() { System.out.println("XXX");} >> void f2() { System.out.println("AAA"); f1();} >> } >> >> class Y extends X { >> void f1() { System.out.println("YYY"); } >> } >> >> class Z extends X { >> void f1() { System.out.println("ZZZ"); } >> } >> public class Main { >> >> static void g(X a) { >> a.f2(); >> } >> public static void main(String[] args) { >> X x =3D new X(); >> Y y =3D new Y(); >> Z z =3D new Z(); >> >> Object obj =3D new Y(); >> ((X) obj).f2(); >> g(z); >> //y =3D (Y)x; >> } >> >> } >> >> I get the following output.. >> >> AAA >> YYY >> AAA >> ZZZ >> >> >> The question is about >> >> Object obj =3D new Y(); >> ((X) obj).f2(); >> >> >> How come YYY, but not XXX, gets printed on the second line? Both f1() >> and f2() are in class X. So shouldn't f1() also have been casted [sic] t= o >> (type) X? The past participle of "to cast" is "cast", not "casted". Casting from a type to a supertype is automatic, so the '(X)' cast in your = code is superfluous. Since 'Y' /is-an/ 'X',. your 'obj' of type 'Y' is alr= eady of type 'X'; no cast needed. (In Java, casting to a parent type is "u= pcasting" or "widening", and comes for free. Casting to an extending type = is "downcasting" or "narrowing", and requires a cast operator.) And no, you should not see the 'X' version of the output from your 'Y' inst= ance, for the reason Arne explained: > ((X) obj).f2();=20 >=20 > and >=20 > ((Y) obj).f2(); >=20 > should give the same output. >=20 > Virtual methods are stored in the object and it really > does not matter what type the ref is declared to. To put it another way, the object instance "knows" its own type. You canno= t call a method on the supertype that exists only in the subtype, but if yo= u call a method that exists in the supertype that the instance's subtype ov= errides, you will get the overridden version. This is a key to how object-oriented programming works. Instances own their own members (methods and variables); the declared type = only controls what the compiler is allowed to see, not how the method behav= es. Arne referred to "virtual methods". That means the method call is dispatch= ed to the instance, not literally called from the reference. The instance = uses its own version of the method - the parent type's if not overridden, t= he derived type's if it is overridden. Read the Java Language Specification (JLS) for the gory details. --=20 Lew