001package beginner; 002 003import com.sandwich.koan.Koan; 004 005import static com.sandwich.koan.constant.KoanConstants.__; 006import static com.sandwich.util.Assert.assertEquals; 007 008public class AboutInheritance { 009 010 abstract class Animal { 011 abstract public String makeSomeNoise(); 012 } 013 014 class Cow extends Animal { 015 @Override 016 public String makeSomeNoise() { 017 return "Moo!"; 018 } 019 } 020 021 class Dog extends Animal { 022 @Override 023 public String makeSomeNoise() { 024 return "Woof!"; 025 } 026 027 public boolean canFetch() { 028 return true; 029 } 030 } 031 032 class Puppy extends Dog { 033 @Override 034 public String makeSomeNoise() { 035 return "Squeak!"; 036 } 037 public boolean canFetch() { 038 return false; 039 } 040 } 041 042 @Koan 043 public void methodOverloading() { 044 Cow bob = new Cow(); 045 Dog max = new Dog(); 046 Puppy barney = new Puppy(); 047 assertEquals(bob.makeSomeNoise(), __); 048 assertEquals(max.makeSomeNoise(), __); 049 assertEquals(barney.makeSomeNoise(), __); 050 051 assertEquals(max.canFetch(), __); 052 assertEquals(barney.canFetch(), __); 053 // but can Bob the Cow fetch? 054 } 055 056 @Koan 057 public void methodOverloadingUsingPolymorphism() { 058 Animal bob = new Cow(); 059 Animal max = new Dog(); 060 Animal barney = new Puppy(); 061 assertEquals(bob.makeSomeNoise(), __); 062 assertEquals(max.makeSomeNoise(), __); 063 assertEquals(barney.makeSomeNoise(), __); 064 // but can max or barney (here as an Animal) fetch? 065 // try to write it down here 066 } 067 068 @Koan 069 public void inheritanceHierarchy() { 070 Animal someAnimal = new Cow(); 071 Animal bob = new Cow(); 072 assertEquals(someAnimal.makeSomeNoise().equals(bob.makeSomeNoise()), __); 073 // cow is a Cow, but it can also be an animal 074 assertEquals(bob instanceof Animal, __); 075 assertEquals(bob instanceof Cow, __); 076 // but is it a Puppy? 077 assertEquals(bob instanceof Puppy, __); 078 } 079 080 @Koan 081 public void deeperInheritanceHierarchy() { 082 Dog max = new Dog(); 083 Puppy barney = new Puppy(); 084 assertEquals(max instanceof Puppy, __); 085 assertEquals(max instanceof Dog, __); 086 assertEquals(barney instanceof Puppy, __); 087 assertEquals(barney instanceof Dog, __); 088 } 089 090 // TODO overriding 091// 092// abstract class ParentTwo { 093// abstract public Collection<?> doStuff(); 094// } 095// 096// class ChildTwo extends ParentTwo { 097// public Collection<?> doStuff() { 098// return Collections.emptyList(); 099// } 100// 101// ; 102// } 103// 104// @Koan 105// public void overriddenMethodsMayReturnSubtype() { 106// // What do you need to change in order to get rid of the type cast? 107// // Why does this work? 108// List<?> list = (List<?>) new ChildTwo().doStuff(); 109// assertEquals(list instanceof List, __); 110// } 111}