001package beginner; 002 003import com.sandwich.koan.Koan; 004 005import static com.sandwich.koan.constant.KoanConstants.__; 006import static com.sandwich.util.Assert.assertEquals; 007import static com.sandwich.util.Assert.fail; 008 009@SuppressWarnings("unused") 010public class AboutCasting { 011 012 @Koan 013 public void longPlusInt() { 014 int a = 6; 015 long b = 10; 016 Object c = a + b; 017 assertEquals(c, __); 018 assertEquals(c instanceof Integer, __); 019 assertEquals(c instanceof Long, __); 020 } 021 022 @Koan 023 public void forceIntTypecast() { 024 long a = 2147483648L; 025 // What happens if we force a long value into an int? 026 int b = (int) a; 027 assertEquals(b, __); 028 } 029 030 @Koan 031 public void implicitTypecast() { 032 int a = 1; 033 int b = Integer.MAX_VALUE; 034 long c = a + b; // still overflows int... which is the Integer.MIN_VALUE, the operation occurs prior to assignment to long 035 assertEquals(c, __); 036 } 037 038 interface Sleepable { 039 String sleep(); 040 } 041 042 class Grandparent implements Sleepable { 043 public String sleep() { 044 return "zzzz"; 045 } 046 } 047 048 class Parent extends Grandparent { 049 public String complain() { 050 return "TPS reports don't even have a cover letter!"; 051 } 052 } 053 054 class Child extends Parent { 055 public String complain() { 056 return "Are we there yet!!"; 057 } 058 } 059 060 @Koan 061 public void downCastWithInheritance() { 062 Child child = new Child(); 063 Parent parentReference = child; // Why isn't there an explicit cast? 064 assertEquals(child instanceof Child, __); 065 assertEquals(parentReference instanceof Child, __); 066 assertEquals(parentReference instanceof Parent, __); 067 assertEquals(parentReference instanceof Grandparent, __); 068 } 069 070 @Koan 071 public void downCastAndPolymorphism() { 072 Child child = new Child(); 073 Parent parentReference = child; 074 // If the result is unexpected, consider the difference between an instance and its reference 075 assertEquals(parentReference.complain(), __); 076 } 077 078 @Koan 079 public void upCastWithInheritance() { 080 Grandparent child = new Child(); 081 Parent parentReference = (Parent) child; // Why do we need an explicit cast here? 082 Child childReference = (Child) parentReference; // Or here? 083 assertEquals(childReference instanceof Child, __); 084 assertEquals(childReference instanceof Parent, __); 085 assertEquals(childReference instanceof Grandparent, __); 086 } 087 088 @Koan 089 public void upCastAndPolymorphism() { 090 Grandparent child = new Child(); 091 Parent parent = (Child) child; 092 // Think about the result. Did you expect that? Why? 093 // How is that different from above? 094 assertEquals(parent.complain(), __); 095 } 096 097 @Koan 098 public void classCasting() { 099 try { 100 Object o = new Object(); 101 ((Sleepable) o).sleep(); // would this even compile without the cast? 102 } catch (ClassCastException x) { 103 fail("Object does not implement Sleepable, maybe one of the people classes do?"); 104 } 105 } 106 107 @Koan 108 public void complicatedCast() { 109 Grandparent parent = new Parent(); 110 // How can we access the parent's ability to "complain" - if the reference is held as a superclass? 111 assertEquals("TPS reports don't even have a cover letter!", __); 112 } 113 114}