Hallmark Problem [Please help]

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

35 Replies - 2559 Views - Last Post: 02 February 2013 - 12:13 PM Rate Topic: -----

#1 k3y  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 205
  • Joined: 25-February 12

Hallmark Problem [Please help]

Posted 30 January 2013 - 12:47 PM

Howdy friends;
I have another assignment that I could use some guidance on. Below I have provided the assignments, my questions, and my code so far.
The Assignment:

Quote

Hallmark has asked you to implement a system for them so that a user can choose from a list of available cards.
There are 9 cards to choose from: Christmas, Valentine's, Birthday, Get well soon, Anniversary, New baby, Thank you, Congratulations, and a blank card.
1) Your program should have at least 9 classes in it that inherit from the abstract card class. (1 for each type of card)
2) Your program should asks the user who the card is for and who it is from.
3) It should also ask them what type of card they would like to create, by giving the user a menu to choose from?
4) If it is a birthday card, it also asks how old the recipient is.
5) If it is a blank card then it asks what personal message the sender would like to include.
6) If it is a Valentine's day card it personalizes the card by adding XOs to the end of the card (hugs and kisses) based on the length of the recipient's name.
The card can be text base. It does not have to be done in a GUI, but it can be done with one if you choose.
Create the cards by extending an abstract class Card and using an abstract method called makeCard that is defined for each card.
The abstract class should look like this:
abstract class Card { String recipient, from; public abstract void makeCard(); }


My Questions:
1) Can I just put all of the classes in one file or do I need to make separate files?
~ this is what I mean: http://www.tutorials...inheritance.htm
If I can, an explanation of some sort would greatly be expected, same for if I can not.
2) Would I customize the cards the way the instructions wanted in the switch statement or somewhere else?

My Code: (I just started, and was confused)
import java.util.*;
public class Hallmark
{
  static Scanner console = new Scanner(System.in);
  public static void main(String[] args)
  {
    //declare variables
    boolean isInt = true;
    int iUserInput;
    int iInputCounter = 1;
    
   //MakeCard userCard = new MakeCard();
    
//menu
    String sMenu = "Please select your card:" + 
      "\n\t1) Christmas" + 
      "\n\t2) Valentines" +
      "\n\t3) Birthday" +
      "\n\t4) Get well soon" +
      "\n\t5) Anniversary" +
      "\n\t6) New Baby" +
      "\n\t7) Thank You" +
      "\n\t8) Congratulations" + 
      "\n\t9) Blank Card\n";
    
    //print menu
    System.out.print(sMenu);
 
    //confirm input
    do
    {
      System.out.println("Please enter a valid choice");
      try
      {
        iUserInput = console.nextInt();
        if (iUserInput >= 0 && iUserInput <= 9)
        {
          iInputCounter--;
          switch(iUserInput)
          {
            case 1: System.out.println("c");
            break;
            
            case 2: System.out.println("v");
            break;
            
            case 3: System.out.println("b");
            break;
            
            case 4: System.out.println("g");
            break;
            
            case 5: System.out.println("a");
            break;
            
            case 6: System.out.println("n");
            break;
            
            case 7: System.out.println("t");
            break;
            
            case 8: System.out.println("co");
            break;
            
            case 9: System.out.println("bl");
            break;
            
            default: System.out.println("in");
            break;
          }
        }
        else
        {
          System.out.println("You have not entered a valid choice");
          continue;
        }
      }
      catch (InputMismatchException e)
      {
        System.out.println("You have entered an invalid input");
        console.next();
        continue;
      }
    }while(iInputCounter > 0);
  }
  // define Card class
  /*public abstract class Card
  {
    //initialize variables
    String sRecipient, sFrom;
    //method call
    public abstract void makeCard();
    */
}



Thank you for any suggestions.

Is This A Good Question/Topic? 0
  • +

Replies To: Hallmark Problem [Please help]

#2 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5481
  • View blog
  • Posts: 11,762
  • Joined: 02-June 10

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 01:49 PM

Until someone with specific JAVA experience can help out, this tutorial on Classes/Objects & Inheritence might help. Its for C# but the two languages are very similar - and the overall concept of objects is all but identical across all OOP languages. In other words: Don't follow the exact syntax but take away the planning and inheritance concepts.

Personally, I know of no advantage to putting all the classes in one file. What do you gain? It just makes for one really long file that requires a lot of searching when you have to maintain a given class.
Was This Post Helpful? 0
  • +
  • -

#3 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7648
  • View blog
  • Posts: 12,902
  • Joined: 19-March 11

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 02:00 PM

A public class must be in its own file, which must be named correctly. Naming is simple: A class named ClassName must be in a file called ClassName.java

Private classes and inner classes must be in a file with some public class.


So you could put all of your child classes in the same file with Card.java, if they're all private classes, but I think it would be simpler to just use public classes.

Differing functionality for the different card types should be specified by the card types themselves - certainly not by the parent class. The parent class defines the shared behavior of the class as a whole, and the child classes provide more specific local behavior.

So your Card class would specify a method which gets information from the user, which would be generic for most cards, and your birthday and blank and VD cards would all override it. The Klingon has given you a good tip with that link: read through that stuff, it'll remind you of the stuff you should have picked up in class.

There is a java-specific tutorial here. This is straight from the source: prepared by Sun and maintained by Oracle.

This post has been edited by jon.kiparsky: 30 January 2013 - 02:03 PM

Was This Post Helpful? 2
  • +
  • -

#4 k3y  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 205
  • Joined: 25-February 12

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 02:30 PM

The parent class contains the generic method in this case makeCard() ~ which gets the recipient and to, and in the special cases I would ask for the specific information. Right? Also how would I incorporate the fancy menu that I made?
Thank you once again

EDIT: code reference below.

//Parent class
abstract public class Card
{
  String sRecipient;
  String sFrom;
  public abstract void makeCard();
}

// Card_Name_Here would be the type of card (subclass)
public class Card_Name_Here extends Card
{
  public void makeCard()
  {
    //
  }
}


This post has been edited by k3y: 30 January 2013 - 02:38 PM

Was This Post Helpful? 0
  • +
  • -

#5 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7648
  • View blog
  • Posts: 12,902
  • Joined: 19-March 11

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 03:10 PM

That looks like a good start. There are a couple of ways you can go from here with makeCard: you could simply define the generic version in Card, and then override it in ValentineCard and BirthdayCard and BlankCard and anywhere else that does something different:

public class Parent {
  public void foo(){
    System.out.println("This is from the superclass"); 
  }
  public static void main(String[] args)
  { 
    Child c = new Child();
    c.foo();
  }
}



public class Child extends Parent{  
  public void foo() {
     System.out.println("This is from the subclass");
  }
}






Or you could define a generic version and call that from the subclass, plus any further stuff you wanted to call:

public class Parent {
  public void foo(){
    System.out.println("This is from the superclass"); 
  }
  public static void main(String[] args)
  { 
    Child c = new Child();
    c.foo();
  }
}



public class Child extends Parent{  
  public void foo() {
      super.foo()
     System.out.println("...and this is from the subclass");
  }
}


There are some more involved things you could do, like inserting hook methods at strategic points in the superclass method, and filling them in in the child classes as needed:


public class Parent {
  public void foo(){
    System.out.println("This is from the superclass"); 
    bar();
    System.out.println("This is another literal line of text");
    baz();
  }

  public void bar(){}   // do nothing here
  public void baz(){}    // do nothing here

  public static void main(String[] args)
  { 
    Parent p = new Parent();
    p.foo();
    Child c = new Child();
    c.foo();
  }
}



public class Child extends Parent{  
  public void foo() {
      super.foo()
     System.out.println("...and this is from the subclass");
  }

  public void bar(){   // fill this in  here
    System.out.println("Something else has happened because this is Child");
  }
  public void baz(){
    System.out.println("And this is another line that didn't happen in the parent class");
}    
}



As you can see, this is just a quick example, and it's probably not the way you want to go, but it might give you something to think about. If this doesn't make sense, don't ask any more questions until you've read through at least the Oracle tutorial that I linked to. A lot of this is explained there.

You could get more advanced and more abstract. I don't want to go all the way into that stuff just now, but you can define a class that simply loops over a list of questions and asks them, and doesn't know what they are and doesn't care. For now, that's probably over your head, though.

This post has been edited by jon.kiparsky: 30 January 2013 - 03:14 PM

Was This Post Helpful? 2
  • +
  • -

#6 k3y  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 205
  • Joined: 25-February 12

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 03:15 PM

Wow, thank you for all of that information. I will try my best to apply it to my current code.
Was This Post Helpful? 0
  • +
  • -

#7 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7648
  • View blog
  • Posts: 12,902
  • Joined: 19-March 11

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 03:20 PM

Oh, as for the the fancy menu, I'd suggest something like this:


        Card card;
          switch(iUserInput)
          {
            case 1: card = new ChristmasCard();
            break;
            
            case 2: card = new ValentineCard();
            break;
           
            // ...
            
            default: card=new BlankCard();
            break;
          }
        }




There's better ways, but that's for another day.
Was This Post Helpful? 1
  • +
  • -

#8 k3y  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 205
  • Joined: 25-February 12

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 03:32 PM

This probably goes in the Card class because it says
Card card


Also the only thing I need the main method for is to instantiate the Card class right?... I know I'm reading the tutorial. However; I am to excited to figure this out.
Was This Post Helpful? 0
  • +
  • -

#9 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7648
  • View blog
  • Posts: 12,902
  • Joined: 19-March 11

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 03:36 PM

Well, that would go in whatever method you run to talk to the user. Looks like it might be in your Hallmark class?

What that line does is it declares a variable of the Card class, and calls it "card". It does not initialize it to anything, that happens in the switch, but since every branch will assign a value, the compiler will pass it.

Of course, once you've done that you can call
card.makeCard();


and it should do the right thing.

This post has been edited by jon.kiparsky: 30 January 2013 - 03:38 PM

Was This Post Helpful? 0
  • +
  • -

#10 k3y  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 205
  • Joined: 25-February 12

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 03:45 PM

View Postjon.kiparsky, on 30 January 2013 - 05:36 PM, said:

Well, that would go in whatever method you run to talk to the user. Looks like it might be in your Hallmark class?

What that line does is it declares a variable of the Card class, and calls it "card". It does not initialize it to anything, that happens in the switch, but since every branch will assign a value, the compiler will pass it.

Of course, once you've done that you can call
card.makeCard();


and it should do the right thing.

I really hate bothering you. However; I really want to grasp this idea and talking with someone helps a ton;
case 1: card = new Christmas();
            card.makeCard();
            break;


This means that the variable card of the type Card will be the object of the Christmas() class. Then this card object will be sent to the makeCard() method, which will be where the card is printed and all that fancy jazz?
Was This Post Helpful? 0
  • +
  • -

#11 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7648
  • View blog
  • Posts: 12,902
  • Joined: 19-March 11

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 04:49 PM

You can just call card.makeCard() after the switch statement: if you write the cases correctly, card will be initialized no matter what branch you're in. (If you don't write it correctly, the compiler will let you know)


Quote

This means that the variable card of the type Card will be the object of the Christmas() class. Then this card object will be sent to the makeCard() method, which will be where the card is printed and all that fancy jazz?


Yes: and if you've understood the material in the tutorial, then you won't be surprised to see that we can declare it as a Card and initialize it as a ChristmasCard (or whatever you're calling it) and it'll work.

Just like you could call the pet shop and say "send me over a mammal". They could send you over a gerbil or a cat or an elephant, and you'd have what you asked for.

Now, you have a Card. You don't know what kind of Card you have, but one thing you know about Cards is that they can do makeCard(). So you tell the card to makeCard, and it does that.

So rather than "sending the card to the method" you're better off thinking of it as "sending a makeCard() message to the card, asking it to perform that method".
Was This Post Helpful? 1
  • +
  • -

#12 k3y  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 205
  • Joined: 25-February 12

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 05:08 PM

I have been reading a number of tutorials/similar questions regarding abstract classes and I have altered my code.
import java.util.*;
public class Hallmark
{
  static Scanner console = new Scanner(System.in);
  public static void main(String[] args)
  {
    //declare variables
    //Card card;
    boolean isInt = true;
    int iUserInput;
    int iInputCounter = 1;
    String sRecipientsName;
    String sSendersName;
    
//menu
    String sMenu = "Please select your card:" + 
      "\n\t1) Christmas" + 
      "\n\t2) Valentines" +
      "\n\t3) Birthday" +
      "\n\t4) Get well soon" +
      "\n\t5) Anniversary" +
      "\n\t6) New Baby" +
      "\n\t7) Thank You" +
      "\n\t8) Congratulations" + 
      "\n\t9) Blank Card\n";
    
    //print menu
    System.out.print(sMenu);
 
    //confirm input
    do
    {
      System.out.println("Please enter a valid choice");
      try
      {
        iUserInput = console.nextInt();
        if ((iUserInput >= 0) && (iUserInput <= 9))
        {
          
          //counter
          iInputCounter--;
          
           //sender and reciever
          System.out.println("Please enter the recipient's name: ");
          sRecipientsName = console.nextLine();
          
          System.out.println("Please enter your name: ");
          sSendersName = console.nextLine();
          
          switch(iUserInput)
          {
            case 1: Christmas c1 = new Christmas();
            break;
            
            case 2: Valentines c2 = new Valentines();
            break;
            
            case 3: Birthday c3 = new Birthday();
            break;
            
            case 4: GetWellSoon c4 = new GetWellSoon();
            break;
            
            case 5: Anniversary c5 = new Anniversary();
            break;
            
            case 6: NewBaby c6 = new NewBaby();
            break;
            
            case 7: ThankYou c7 = new ThankYou();
            break;
            
            case 8: Congratulations c8 = new Congratulations();
            break;
            
            default: BlankCard c9 = new BlankCard();
            break;
          }
        }
        else
        {
          System.out.println("You have not entered a valid choice");
          continue;
        }
      }
      catch (InputMismatchException e)
      {
        System.out.println("You have entered an invalid input");
        console.next();
        continue;
      }
    }while(iInputCounter > 0);
  }
}


abstract class Card
{
  String sRecipient;
  String sSender;
  abstract void makeCard();
}


Christmas in this case would be replaced by the various types of cards names.
class Christmas extends Card
{
  void makeCard()
  {
    System.out.println("blah");
  }
}



I am unsure if this is the way to go, I am using it as if it is an interface. I have no errors upon compilation however, is there anyway to add some parameters so I can test the makeCard() and make sure the to and from work? sort of like this: http://www.tutorials..._interfaces.htm . Or maybe I am completely wrong. I see the end of the tunnel... any help is greatly appreciated.

This post has been edited by k3y: 30 January 2013 - 05:17 PM

Was This Post Helpful? 0
  • +
  • -

#13 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7648
  • View blog
  • Posts: 12,902
  • Joined: 19-March 11

Re: Hallmark Problem [Please help]

Posted 30 January 2013 - 07:28 PM

Is there any reason you're using different variable declarations for each card in your switch statement? This will make it impossible to make full use of the inheritance from Card to each of Card's subtypes.


You can test your Cards simply enough by writing a testing class:
public class CardTester 
{
  public static void main(String[] args)
  {
    Card christmas = new Christmas();
    christmas.makeCard();

    etc....
  }
}


Put experiments in the tester class and try them. See if they work.

If you want, you can make the experiments into methods of that class: then you can either edit the main to run the tests that you're interested in now, or you can arrange to select a test to run.

And you know, at that point you're going in a very right direction, so you should continue to play with these ideas. Try to make a testing class which is easy to run and informative. Think about how this can help you in developing your classes.

This is a hugely important idea, so it's good that you're thinking about it: follow it further!
Was This Post Helpful? 0
  • +
  • -

#14 k3y  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 205
  • Joined: 25-February 12

Re: Hallmark Problem [Please help]

Posted 31 January 2013 - 12:56 PM

Alright, I have been doing alot of tweaking and think I may have found a way to pull this off. I would like to call a method(s) to get the user input (to, from) and in the special cases I will have a special set of methods. I would then pass those as parameters to the classes. Hopefully you can see what I am trying to do and advise me on a straight path.
Any help is appreciated.
import java.util.*;
public class Hallmark
{
  static Scanner console = new Scanner(System.in);
  public static void main(String[] args)
  {
    boolean isInt = true;
    int iUserInput;
    int iInputCounter = 1;
    String sRecipient = toPerson();
    String sSender = fromPerson();
    
//menu
    String sMenu = "Please select your card:" + 
      "\n\t1) Christmas" + 
      "\n\t2) Valentines" +
      "\n\t3) Birthday" +
      "\n\t4) Get well soon" +
      "\n\t5) Anniversary" +
      "\n\t6) New Baby" +
      "\n\t7) Thank You" +
      "\n\t8) Congratulations" + 
      "\n\t9) Blank Card\n";
    
    //print menu
    System.out.print(sMenu);
 
    //confirm input
    do
    {
      System.out.println("Please enter a valid choice");
      try
      {
        iUserInput = console.nextInt();
        if ((iUserInput >= 0) && (iUserInput <= 9))
        {
          
          //counter
          iInputCounter--;
                 
          switch(iUserInput)
          {
		  //christmas card
            case 1: 
			toPerson();
			fromPerson();
			Christmas c1 = new Christmas();
            c1.makeCard(sSender, sRecipient);
            break;
			
			//valentines card
            case 2:
			toPerson();
			fromPerson();
			Valentines c2 = new Valentines();
            c2.makeCard(sSender, sRecipient);
            break;
            
			//birthday card
            case 3: 
			toPerson();
			fromPerson();
            Birthday c3 = new Birthday();
            c3.makeCard(sSender, sRecipient);
            break;
            
			//getwellsoon card
            case 4:
			toPerson();
			fromPerson();
			GetWellSoon c4 = new GetWellSoon();
            c4.makeCard(sSender, sRecipient);
            break;
            
			//anniversary card
            case 5:
			toPerson();
			fromPerson();
			Anniversary c5 = new Anniversary();
            c5.makeCard(sSender, sRecipient);
            break;
            
			//newbaby card
            case 6:
			toPerson();
			fromPerson();
			NewBaby c6 = new NewBaby();
            c6.makeCard(sSender, sRecipient);
            break;
            
			//thankyou card
            case 7:
			toPerson();
			fromPerson();
			ThankYou c7 = new ThankYou();
            c7.makeCard(sSender, sRecipient);
            break;
            
			//congratulations card
            case 8:
			toPerson();
			fromPerson();
			Congratulations c8 = new Congratulations();
            c8.makeCard(sSender, sRecipient);
            break;
            
			//blank card
            default:
			toPerson();
			fromPerson();
			BlankCard c9 = new BlankCard();
            c9.makeCard(sSender, sRecipient);
            break;
          }
        }
        else
        {
          System.out.println("You have not entered a valid choice");
          continue;
        }
      }
      catch (InputMismatchException e)
      {
        System.out.println("You have entered an invalid input");
        console.next();
        continue;
      }
    }while(iInputCounter > 0);
  }
  public Object toPerson()
  {
		System.out.println("Please enter your name");
		String sSender = console.nextLine();
		return sSender;
	}
	public Object fromPerson()
	{
		System.out.println("Please enter recipients name");
		String sRecipient = console.nextLine();
		return sRecipient;
	}
}


The card class
public abstract class Card
{
  String sRecipient;
  String sSender;
  public abstract void makeCard();
}


The christmas card class(I will model other subclasses off of this class
public class Christmas extends Card
{
  Christmas(String sSender, String sRecipient)
  {
    sRecipient = tocard;
    sSender = FromCard;
  }
  public void makeCard()
  {
    System.out.println("christmas");
  }
}



Once again any help is greatly appreciated.
Was This Post Helpful? 0
  • +
  • -

#15 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7648
  • View blog
  • Posts: 12,902
  • Joined: 19-March 11

Re: Hallmark Problem [Please help]

Posted 31 January 2013 - 01:30 PM

Use the inheritance.

Your Hallmark object is handling exactly one Card, right? So it should declare and use exactly one Card object, and that Card object should be declared as a Card (not a Christmas or a Birthday, or whatever). When you go to put an object in it, you might put a Christmas or a Blank or a Secretary's Day card or whatever in there, but all the Hallmark class knows is, it's got a Card.

That's the point of object inheritance: all Cards can do makeCard, and they all have the same constructor, so you don't need to do

            toPerson();
            fromPerson();
            Congratulations c8 = new Congratulations();
            c8.makeCard(sSender, sRecipient);
            break;



in every branch of the switch. All you need to do in the switch is
card = new Congratulations();
break;



and then after the switch you do this:

            toPerson();
            fromPerson();
            card.makeCard(sSender, sRecipient);



The Hallmark class doesn't care what kind of Card it has: all it knows is that Cards can do makeCard, and that's what it wants to do. So why should it need to worry about whether its card is a Christmas or a Congratulations, or whatever? That's just making your code a mess. (for example, how are you going to refer to that object that you created, later on, if you don't know which one ended up getting created?)


Also, several things wrong here:


  public Object toPerson()
  {
        System.out.println("Please enter your name");
        String sSender = console.nextLine();
        return sSender;
    }




+1 for putting functionality into a method. That's a good instinct. Now, why on earth are you returning an Object? The Object is a String, and you know it's a String, so why confuse yourself and the compiler by bleaching it out to Object?
Also, why are you calling this again in the switch statement? You've called it before, and assigned the result to a String, now you're calling it again and dropping the return value on the floor?
And since I mention it - I'm pretty sure this won't even compile, since you're trying to stuff an Object into a String:

String sRecipient = toPerson();


So that's going to need a good bit of work.
Was This Post Helpful? 1
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3