Thursday, March 11, 2010

Simple things that we forget

Create a few simple classes (one extends the other)
   1: class A {
   2:     public String prop_a1 = "property a1";
   3:  
   4:     public String method_a2() {
   5:         return "return from method_a2";
   6:     }
   7: }


   1: class B extends A {
   2:     public String prop_b1 = "property b1";
   3:     public String method_b2() {
   4:         return "return from method_b2";
   5:     }
   6: }

Now test the methods from inheritance chain...


   1: class C {
   2:     public static void main(String [] args) {
   3:         A a = new B(); // this is upcasting
   4:  
   5: System.out.println(a.prop_a1);
   6:         System.out.println(a.method_a2());
   7:  
   8:  
   9:         /**
  10:         ** The following code is compile-time error
  11:         ** System.out.println(a.prop_b1);
  12:         ** System.out.println(a.method_b2());
  13: 
  14:                 C:\Java\test4>javac A.java
  15:                 A.java:24: cannot find symbol
  16:                 symbol : variable prop_b1
  17:                 location: class A
  18:                 System.out.println(a.prop_b1);
  19:                                    ^
  20:                 A.java:25: cannot find symbol
  21:                 symbol : method method_b2()
  22:                 location: class A
  23:                 System.out.println(a.method_b2());
  24:                                    ^
  25:                 2 errors
  26:             **/
  27:  
  28:  
  29:  
  30:  
  31:         B b = new A();
  32:         /**
  33:          ** B b = new A();
  34:          ** The above code is "downcasting" [I stand corrected]
  35:          * C:\Java\test4>javac A.java
  36:                 A.java:45: incompatible types
  37:                 found : A
  38:                 required: B
  39:                 B b = new A();
  40:                 ^
  41:                 1 error
  42:             **/
  43:  
  44:             B b = (B)new A();
  45:                 /**
  46:                   * Casting will compile
  47:                   * But causes a runtime error
  48:                  **/
  49:  
  50:         }
  51: }





 





[Edit]


Looking at the comments below, I feel compelled to write the reason for these snippets of code. In ActionScript 3.0, the following works in standard mode (deferred type checking)



   1: class ClassBase
   2: {
   3: }

You can subsequently create a subclass of ClassBase named ClassExtender, which has one property named someString, as follows:



   1: class ClassExtender extends ClassBase
   2: {
   3:     var someString:String;
   4: }

and finally:



   1: var myClass:ClassBase = new ClassExtender();
   2: myClass.someString = 
   3: "hello";
   4: // no error in ActionScript 3.0 standard mode

 


[Edit]

Few more: public static void main(String[] args) { int i = 10; Integer I = new Integer(10); System.out.println("I == i : "+ (I == i)); // true System.out.println("I.equals(i) : "+ I.equals(i)); // true long l = 10L; System.out.println("I == l : " + (I == l)); // true Long L = new Long((long)10); System.out.println("I == L : Compiler Error...Incompatible datatypes"); System.out.println("I.equals(L) : " + I.equals(L)); // false }

2 comments:

Arun Madas said...

Dost, Upcasting is allowed in java.

A a = new B(); is valid
Reason is when you create instance of B, you have memory allocated for all the variables and methods in B along with variables and methods of A (as B extends A).

In this case, a (instance of A) can still point to those references created by the larger instance memory B.

Ideally programmer would want to do A a = (A) new B(); to clarify but this is done automatically. This is upcasting (assining derived class instance to base class).

On the contrary,
B b = new A(); is invalid. Compiler will throw error. The mapping of variables and methods references in A cannot completely full-fill larger object instance b (instance of B) as B itself has some variables and methods which are not instantiated yet (not possible). This is called downcasting (mapping base class instances to derived classes - not allowed)

Kromanium said...

Basic point was that a type A instantiated with B (as you rightly point out is upcasting) cannot use the methods of B. (i.e.
a.method_B();)

..And I stand corrected, which now reflects above.

The other point is;
B b = new A(); // compiler Error
But:
B b = (B) new A(); // passes the compiler, but will cause an error when you try to access any methods.