/** * Class Biscuit is an example of an object * NB: Our American friends would call this a Cookie * * I'm using this as a teaching example so there are many redundant comments * Each student in the group is developing their own Class in parallel * * General hints and tips on style are given at the end of the Class * * @author Mr J * @version 1.0 */ public class Biscuit2 { // constants private static final int ITEMS = 5; private static final String SEPARATOR = "&"; // data members private char shape; // the biscuit shape - coded, eg R = round private String taste; // well, taste private double price; // um, the price private int unit; // the number of biscuits the price applies to private boolean myFavourite; // true if this is my favourite biscuit /** * "No argument" constructor sets the values arbitrarily */ public Biscuit2() { // special biscuit with "no" properties this.shape = 'x'; this.taste = "None"; this.price = 0.0; this.unit = 0; this.myFavourite = false; } /** * Constructor sets the values using parameters * * @param the biscuit shape - coded, eg R = round * @param the taste (or flavour) of the biscuit * @param the price of the biscuit in dollars and cents * @param the number of biscuits the price applies to * @param true if this is my favourite biscuit */ public Biscuit2( char shape, String taste, double price, int unit, boolean myFavourite ) { setShape(shape); setTaste(taste); setPrice(price); setUnit(unit); setMyFavourite(myFavourite); } /** * Constructor sets the values using a String created by toString() method */ public Biscuit2(String s) { // split the String as in BiscuitDisplay Class String[] theBits = new String[ITEMS]; theBits = s.split(SEPARATOR); // convert test bits into appropriate types as in BiscuitDisplay Class try { setShape(theBits[0].charAt(0)); setTaste(theBits[1]); setPrice(Double.parseDouble(theBits[2])); setUnit(Integer.parseInt(theBits[3])); setMyFavourite(Boolean.parseBoolean(theBits[4])); } catch(Exception e) { // some problem, return some kind of ErrorBiscuit!! this.shape = '-'; this.taste = "error"; this.price = 0.0; this.unit = 0; this.myFavourite = false; } } // Mutator methods, change a data member /** * This method sets the shape of the Biscuit * * @param the shape type of the biscuit (eg R = round, S = square) */ public void setShape(char shape) { // We'll make sure our shape is represented by a capital // letter. If the shape is not one of our "recognised" // acceptable shapes, we'll set it to "other" shape = Character.toUpperCase(shape); if ( (shape == 'R') || (shape == 'S') ) { // The this keyword is used to make sure we are referring to // the Class data member not a local variable of the same name. // It's not essential but just good practice. this.shape = shape; } else { // set it to "Other" this.shape = 'O'; } } /** * This method sets the taste of the Biscuit * * @param the taste description of the biscuit */ public void setTaste(String taste) { // It is not sensible to validate this property // of a biscuit. (Any String will be accepted) this.taste = taste; } /** * This method sets the price of the Biscuit * * @param the price of the biscuit ( > 0 and < 100) */ public void setPrice(double price) { // (A price between 0 and 99.99 seems sensible) if ( (price > 0.0) && (price < 100.0) ) { this.price = price; } else { // back to our "default value" this.price = 0.0; } } /** * This method sets the unit of the Biscuit * The unit is the base number the price applies to, eg * A pack of 24 biscuits. * * @param the unit of the biscuit ( single, or size of pack, for example) */ public void setUnit(int unit) { // (A unit between 1 and 100 seems sensible) if ( (unit > 0) && (unit <= 100) ) { this.unit = unit; } else { // back to our "default value" this.unit = 0; } } /** * This method defines whether this is my favourite biscuit * As you may know, I'm a Douglas Adams fan. Therefore, in * the interests of introducing a certain mild tension I * won't tell you what my favourite biscuit is just yet :-) * * @param whether this biscuit is my favourite. */ public void setMyFavourite(boolean iLikeThisOne) { // I've used a differently named parameter, just to show I can this.myFavourite = iLikeThisOne; } /** * This method returns the shape of the Biscuit * * @return the code representing shape of the biscuit */ public char getShape() { // recall that the this keyword can always be used with the // Class data members to avoid ambiguity. return this.shape; } /** * This method returns the taste of the Biscuit * * @return the description of this biscuit's taste */ public String getTaste() { return this.taste; } /** * This method returns the price of the Biscuit * * @return the price of this biscuit */ public double getPrice() { return this.price; } /** * This method returns the unit * * @return the unit size of this/these biscuit(s) */ public int getUnit() { return this.unit; } /** * This method returns if this Biscuit is my favourite * * @return true if this is my favourite biscuit */ public boolean isMyFavourite() { // notice that with booleans we use "is" rather than "get" // this is by convention and reads more sensibly too. return this.myFavourite; } /** * This method overrides toString() of Class Object * * @return a String represenation of the biscuit */ public String toString() { return ( getShape() + SEPARATOR + getTaste() + SEPARATOR + getPrice() + SEPARATOR + getUnit() + SEPARATOR + isMyFavourite() ); } } /** * Elements of good style (recommended by the language designers): * * Please use an initial capital letter for the Class name. * Use lowercase letters for the data members and methods * Use internal capitals rather than underscores: myFavourite, not my_favourite * Use consistent indentation schemes * Always add comments * * Recommended by me: * * Keep the data members and methods in the same order, ie if shape is * your first data member then make setShape your first mutator method * Add comments as soon as you write the method - comments are for other * humans, not for yourself or the computer, so make them meaningful! * */