I am a reader of 'Thinking in Java' and now had an OO design question... The question is a little difficult.... (I am from Taiwan , I can only use easier English) From 'Thinking in Java 2nd edition' page 360 , Month2.java Bruce introduced a design trick , that uses Month2 for each Month's type. I want to rewrite this code and implement 'Comparable' interface , as follows :
After this , I want to introduce a 'Season' interface as following:
This interface is very simple , just wrap a 'feeling' to each MyMonth In Northern Hemisphere , For example : March,April,and May are 'warm' , so , getFeeling() should return 'warm' and June,July,Auguse are 'hot' , so , getFeeling() return 'hot' ...etc
To accomplish this , I extend MyMonth and implements SeasonIF, The new class is named "NorthMonth.java" (Northern Hemisphere) The code is as follows :
OK, here is the problem , in fact , the code above is incorrect. Because 'getIndex()' is from 'MyMonth' and it looks up the index from 'MyMonthList', It will never find getIndex(NorthMonth) from 'MyMonthList', therefore , the return value will always be '-1'.
But I don't know how to overcome this , let's skip this... And if I write a client to test my NorthMonth , the result will be :
I know the error's origin is '(NorthMonth)(MyMonth.APR)' but I don't know how go fix it....
I've tried many ways to rewrite my client code (testNorthMonth.java) and NorthMonth.java , but I find no way to solve the problem 'elegantly' ...
The only solution I found is very DIRTY :
I have to re-code almost all 'MyMonth.java' to 'NorthMonth.java' including initializing twelve static NorthMonth (from JAN to DEC) , private static NorthMonth NorthMonthArray , private static List NorthMonthList = Arrays.asList(NorthMonthArray) , public int getIndex(NorthMonth nm) , public int compareTo()...
By this way , it really works , but it is too dirty .... It lacks the 'elegance' , 'elasticity' and 'code-reusability' of Object-oriented Java
If there are some presuppositions: 1. Do not initialize 12 static NorthMonth in NorthMonth.java 2. Do not re-code getIndex() and compareTo() , which should be handled by MyMonth.java 3. Only implement getFeeling() 4. In MyMonth.java , each month is 'MyMonth' , not integer-based 5. MyMonth not abstract .
Do you have better idea how to improve the design ? Thank you very much.
Best regards. [ edited to preserve formatting using the [code] and [/code] UBB tags -ds ] [ August 11, 2002: Message edited by: Dirk Schreckmann ]
Without going in detail in your code, I wanted to pointout that in the first line of above code you are trying to take the static data member APR from MyMonth class and cast it to NorthMonth type. Well there is no data member called APR in this class. You would either have to create an object of MyMonth with name "APR" and caste it or create a static data member called APR in this class. Hope this gives you some clue...
Thanks. Barkat [ August 11, 2002: Message edited by: Barkat Mardhani ] [ edited to break apart super long lines of code -ds ] [ August 12, 2002: Message edited by: Dirk Schreckmann ]
Joined: Jul 11, 2001
Hi smallufo, I think your problem is mainly caused by using inheritance - isn't it rather that a month is *associated* to a season? How are these classes used, btw?
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Joined: Jul 28, 2002
Your problem is that you're casting backwards. Look at this: Object --->MyMonth -------->NorthMonth OK, MyMonth is an Object, correct? So I can do: Object obj = (Object) new MyMonth("Jan"); HOWEVER, Object is NOT a MyMonth. So this is WRONG: //WRONG CODE MyMonth month = (MyMonth) new Object("Jan"); So your class NorthMonth can be cast to a MyMonth: //OK CODE MyMonth month = (MyMonth) new NorthMonth("Jan"); But since NorthMonth inherits from MyMonth, there's no need to create a MyMonth first, simply do this in main: NorthMonth northApril = new NorthMonth("April"); and do smth like this in NorthMonth:
(By the way, that will also take care of your other problem)