Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Assignment in Java Understand the Classes and Problem Every message contains som

ID: 3695570 • Letter: A

Question

Assignment in Java

Understand the Classes and Problem

Every message contains some content ("The British are coming! The British are coming!" and a creator, or author ("Paul Revere"). We could enhance these by adding other traits (date and/or time of creation), but let's keep things simple and say that these are the only two aspects of a basic message.

Some messages, however, have further components that define them. For example, an email consists of a normal message, plus at least two other items: a from email address and a to email address. An email is a message, but a special kind of message. So we can smell inheritance in the neighborhood. A message seems like it will make a good base class, and an email, having an is a relationship with message, is a good candidate for a derived class or extension of the base class message.

Meanwhile, a tweet consists of a normal message, plus at least one other item: a from user id. An tweet is a message, too. It has a different kind of specialization than an email has, so it is a different extension of the base class. (We are not considering a direct tweet, which would also require a to user id.)

Not only will both emails and tweets contain extra data than the base class, message, but in at least one instance we will see the same member (the content) have a different kind of restriction in the derived class than in the base class (can you guess what I'm suggesting before you read on?). Thus, even though we store the tweet content in the base class member, without the need for a new content area for the tweet, we will still have a different validation of the length of that message content.

Warning: Because it makes sense to do so, we are going to name the message content message and the message class Message. So what I called content in the above paragraph will be known as (lower-case) message in what comes next. The class, itself, will be (upper-case) Message. You'll see. Just keep reading.]

File Structure: I prefer one file for the entire program, so the non-Foothill classes should be non-public.

The Base Class: Message

Your base class is named Message.

Public or Protected (your choice) Static Class Constants

Define a full set of limits and defaults, like MAX_MSG_LENGTH and DEFAULT_AUTHOR, for both min, max lengths and default data of every member. Set the maximum message length to a large number (at least a million) and the maximum author length to a reasonable value like 40 or 65, not 5 or 200.

Private Member Data

Public Methods

Default and 2-parameter constructors.

Mutator and Accessor for each member.

a toString() method that provides a nicely formatted return String for potential screen I/O.

Private Methods

private static validation helpers to filter client parameters. These will support your public methods.

Recommended test of Class Message

Instantiate two or more Message objects, some using the default constructor and some using the parameter-taking constructor. Mutate one or more of the members, and after that use the toString() to assist a screen output so we can see what all of your objects contain. Next, test one or more accessors. Finally, test two or more mutators, providing both legal and illegal arguments and testing the return values (thus demonstrating that the mutators do the right thing). Here is a sample run from my test (but you will have to imagine/deduce the source I used and create your own source for your testing, which will produce a different output).

Example Test Run of Message Class

The Derived Class: Email

Your first derived class is named Email. Email uses the two members already present in the base class; the Email's message is the message of the base class, and the author of the base class is the Emails's author's actual name (not the from email address which I will introduce next). Do not try to store an Email's message body or author as a new member of the derived class or you will get -20 points -- not desirable by you or me. Duplicating base class data in derived class means you do not understand what inheritance is, thus the significance of this kind of mistake.

Public Static Class Constants

To the existing base class statics, add at least two with names and meanings similar or identical to MAX_EMAIL_ADDRESS_LENGTH and DEFAULT_EMAIL_ADDRESS. Look up the maximum length of an email address, and make yours is no larger than that (but you can make is smaller for easier testing).

Additional Private Member Data

Public Methods

Default and 4-parameter constructors. Use constructor chaining.

Mutator and Accessor for the new members.

Override those methods of the base class for which it makes sense to do so. Think about this and come to your own conclusions.

Private Methods

private static validation helper to filter a bad email address. You should do the minimum, but you don't have to be more complete than that. This is just to show that you can perform basic filtering. The minimum is a method isValidEAddr() (or similarly named) which tests for both length and the existence of at least one '@' and one '.' character. Further is up to you, but don't overdo it or be too restrictive.

Recommended test of Class Email

Similar to the Message class.

Example Test Run of Email Class (done in same run as overall program run)

The Derived Class: Shweet

(It is like a Twitter Tweet, but since I can't be certain that the details of a Tweet are exactly what I state here, we will disengage this from Twitter, and make the constraints that I impose accurate for a Shweet by decree.)

Shweet uses the two members already present in the base class; The Shweet's message is the message of the base class, and the author of the base class is the Shweet's author's actual name (not the Shwitter ID which I will introduce next). Do not try to store a Shweet's message body or author as new members or you will get -20 points, as mentioned above.

Public Static Class Constants

To the existing base class statics, add three with a names and meaning similar or identical to MAX_SHWITTER_ID_LENGTH (15), MAX_SHWEET_LENGTH (140) and DEFAULT_USER_ID. Look up and use the actual maximum lengths of the first two constants.

While the MAX_SHWEET_LENGTH is going to be smaller than the base class's MAX_MSG_LENGTH, do not assume this fact in your implementation. A valid message length for a Shweet has to be smaller than both of these values. If it's not a valid base class message, it isn't a valid Shweet message, and this should be true if we later change the MAX_SHWEET_LENGTH length to be 50 million.

Additional Private Member Data

Public Methods

Default and 3-parameter constructors. When it is possible and meaningful, use constructor chaining. Think about which constructor to chain to.

Mutator and Accessor for the new member.

Override those methods of the base class for which it makes sense to do so. Think about this and come to your own conclusions. You have to somehow enforce the length limits of both the base class and the derived class for the same message member.

Private Methods

private static validation helpers (plural) to filter out bad tweets and shwitter IDs. Create an isValidShweet() for the message. Also, create an isValidShwitterID() for the Shwitter ID. But also, make a third, even lower-level, helper that would make isValidShwitterID() clear and short. This helper-helper should be named something like stringHasOnlyAlphaOrNumOrUnderscore() and that name tells you the kind of thing it should do: it should make sure the shwitter ID contains only some combination of letters, numbers or an underscore ('_').   The name of this method is fine - don't try to apply boolean logic to it as there is no way to do so. The definition is what you care about. Also, I don't care whether you decide that the Shwitter ID be case sensitive. If you don't know that String or Character methods can be used for this, look them up online. They are very easy to find.

Recommended test of Class Shweet

Similar to the Message class.

Example Test Run of Shweet Class (done in same run as overall program run)

OPTION B - A Stack of Messages

Complete, for submission, OPTION A. Add StackNode and Stack classes, exactly as presented in the Modules. (I prefer one file, so these new classes should be non-public). Next, derive MessageNode and MessageStack classes in the same manner as we derived FloatNode and FloatStack in the modules, but making adjustments, as needed, to have the MessageStack work with Messages. Change any methods named showXYZ() by converting them to toString() so that the client, not the methods, does the output. The new toString() method (or methods) merely format(s) the Strings in preparation for output.

In your client, after you have done the things from OPTION A, add code to create a MessageStack. Then pushMessage() all the various Messages onto the stack. This means that some messages will be base class objects and some will be derived class objects. But the code to push and pop them in the client is the same. Nothing special need be done in order to  push one kind of Message vs. another kind. That is, if you are doing this right, you just pushMessage(someMsg) regardless of what flavor of Message someMsg happens to be, and likewise with the popping.

Finally, in a loop, popMessage() everything off the MessageStack and print it out as you popMessage(). Go beyond the end of the Stack so you can confirm that your code does not break when you popMessage() things off an empty Stack.

If working correctly, this option will print the base class data if a base class object is popped off the stack, but will print the extra derived data if a derived class object is popped. This is a consequence of overriding toString() which is already part of OPTION A. This has to happen by just calling toString() on the pop()ped references without the client having to do anything special.

Explanation / Answer


class Foothill
{
   public static void main(String[] args)
   {
      Message testMsg1, testMsg2, testMsg3;
      testMsg1 = new Message();
      testMsg2 = new Message("My life for Aiur!");
      testMsg3 = new Message("");
    
      String longString = new String("LOL");
    
      while (longString.length() < Message.MAX_MSG_LENGTH + 1)
         longString += "LOLLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOL";
    
      System.out.println("---Tests of Base Class---- ");
    
      //Show initial messages using toString()
      System.out.println("---Initial messages using toString(): " +
                         "Message 1: " + testMsg1.toString() +
                         "Message 2: " + testMsg2.toString() +
                         "Message 3: " + testMsg3.toString());
    
      //Mutate some members then display all w/ toString()
      testMsg1.setMessage("Goodbye cruel world!");
      testMsg3.setMessage("IT IS GOOD TO BE A VALID MESSAGE!");
    
      System.out.println("---Mutated msg1, msg3. Showing w/ toString(): " +
                         "Message 1: " + testMsg1.toString() +
                         "Message 2: " + testMsg2.toString() +
                         "Message 3: " + testMsg3.toString());
    
      //Testing accessor
      System.out.println("---Testing message accessor: " +
                         " Message 1: " + testMsg1.getMessage() +
                         " Message 2: " + testMsg2.getMessage() +
                         " Message 3: " + testMsg3.getMessage());
    
      //Testing mutator
      System.out.println("---Testing message mutator: ");
      if (testMsg1.setMessage("k"))
         System.out.println("Successfully mutated testMsg1");
      else
         System.out.println("Failed to mutate testMsg1");
    
      if (testMsg2.setMessage(longString))
         System.out.println("Successfully mutated testMsg2");
      else
         System.out.println("Testmsg2 mutate too long (expected)");
    
      if (testMsg3.setMessage(""))
         System.out.println("Successfully mutated testMsg3! ");
      else
         System.out.println("Testmsg3 mutate too short (expected) ");
    
      //--------End base class tests
      System.out.println("******END OF BASE CLASS TESTS*******");

      //---Tests of derived class email----
      Email email1, email2, email3;
      email1 = new Email();
      email2 = new Email("Hello there", "Cliff@Foothill.edu", "JA@AOL.com");
      email3 = new Email("Invalid address here", "Bob@Bob.com", "email");
    

      System.out.println("---Tests of Derived Class Email---- ");
    
      //Show initial messages using toString()
      System.out.println("---Initial Emails using toString(): " +
                         "Email 1: " + email1.toString() +
                         "Email 2: " + email2.toString() +
                         "Email 3: " + email3.toString());
    
      //Mutate some members then display all w/ toString()
      email1.setFromAddress("Thisemailaddresswillnotbevalid");
      email2.setFromAddress("@. trying to exceed the maximum length for " +
                            "emails is not so easy because things have to be" +
                            "very extended you see and if they're not then");
      email1.setMessage("this is a new email message");
      email3.setToAddress("email@email.email");
    
      System.out.println("---Mutated emails.Showing w/ toString(): " +
                         "Email1 : " + email1.toString() +
                         "Email2 : " + email2.toString() +
                         "Email3 : " + email3.toString());
    
      //Testing accessor
      System.out.println("---Testing derived class(Email) accessor: " +
                         " Email1 : " + email1.getFromAddress() +
                         " Email2 : " + email2.getToAddress() +
                         " Email3: " + email3.getMessage());
    
      //Testing mutator
      System.out.println("---Testing message mutator: ");
      if (email1.setFromAddress("k"))
         System.out.println("Successfully mutated fromAddress of email1");
      else
         System.out.println("Failed to mutate fromAddress email1");
    
      if (email2.setToAddress(longString))
         System.out.println("Successfully mutated email2");
      else
         System.out.println("email2 mutate too long (expected)");
    
      if (email3.setToAddress(""))
         System.out.println("Successfully changed toAddress of email3! ");
      else
         System.out.println("Email3 mutate too short (expected) ");
    
      if (email3.setToAddress("Eduardo.....Hello!!.com"))
          System.out.println("Successfully changed toAddress of email3 ");
      else
          System.out.println("Missing '@' character for email3 (expected) ");
    
      //---End of tests of Email derived class-----
      System.out.println("******END OF EMAIL CLASS TESTS******* ");

      //---Tests of derived class Shweet----
      Shweet shweet1, shweet2;
      shweet1 = new Shweet();
      shweet2 = new Shweet("WOW I M A SHWEET", "hardenMan");

      System.out.println("---Tests of Derived Class Shweet---- ");
    
      //Show initial messages using toString()
      System.out.println("---Initial Shweets using toString(): " +
                         "Shweet 1: " + shweet1.toString() +
                         "Shweet 2: " + shweet2.toString());
    
      //Mutate some members then display all w/ toString()
      shweet1.setMessage("Guacamole, we've got a shweet!");
      shweet1.setID("N0_SP4CES");
      shweet1.setID("No spaces allowed");
      shweet2.setMessage("New valid shweet");
    
      System.out.println("---Mutated Shweets.Showing w/ toString(): " +
                         "Shweet1 : " + shweet1.toString() +
                         "Shweet2 : " + shweet2.toString());
    
      //Testing accessor
      System.out.println("---Testing derived class(Shweet) accessor: " +
                         " shweet1 msg : " + shweet1.getMessage() +
                         " shweet2 ID : " + shweet2.getID() +
                         " shweet1 ID: " + shweet1.getID() + " ");
    
      //Testing mutator
      System.out.println("---Testing shweet mutator: ");
      if (shweet1.setMessage(longString))
         System.out.println("Successfully changed shweet of shweet1 ");
      else
         System.out.println("shweet1 too long (expected) ");
    
      if (shweet1.setID("_shwitIDD_69"))
         System.out.println("Successfully changed id shweet1 (expected) ");
      else
         System.out.println("failed to change id of shweet1 ");
    
      if (shweet2.setMessage("Should be a valid Shweet!! Yay"))
         System.out.println("Successfully changed shweet2 msg (expected) ");
      else
         System.out.println("Failed to change shweet of shweet2 ");
    
      if (shweet2.setID("&&invalidcharacters"))
          System.out.println("Successfully changed ID of shweet2 ");
      else
          System.out.println("invalid characters for shweet2 Id (expected)");
    

    
   }

}

class Message
{
   //--static class constants
   public static final int MIN_MSG_LENGTH = 1;
   public static final int MAX_MSG_LENGTH = 100000;
   public static final int DEFAULT_MSG_LENGTH = 10;
   public static final String DEFAULT_MSG = "(invalid message)";

   //--private member data
   private String message;



   //--public class methods
   //Default constructor for Message class. Takes no parameters, simply sets
   //the private data member message as the DEFAULT_MSG for the class.
   public Message()
   {
      message = new String(DEFAULT_MSG);
   }
   //Overloaded constructor for the Message class.    public Message(String userMessage)
   {
      if (!validMessage(userMessage))
         message = new String(DEFAULT_MSG);
      else
         message = new String(userMessage);
    
   }
   //Simple getter for private data member, message, as its data type (String).
   //Returns message as a String.
   public String getMessage()
   {
      return message;
   }
   //setMessage is a mutator for the private member message of the Message
   //class. public boolean setMessage(String messageInput)
   {
      if (!validMessage(messageInput))
         return false;
    
      message = messageInput;
      return true;
   }
   public String toString()
   {
    
      String returnString = new String();
      if (validMessage(message))
         returnString += message + " ";
    
      return returnString;
   }
   //validMessage is a boolean helper function that takes in a String,
   //testMessage. private boolean validMessage(String testMessage)
   {
      if (testMessage.length() > MAX_MSG_LENGTH ||
          testMessage.length() < MIN_MSG_LENGTH)
         return false;
    
      return true;
   }
    

}

class Email extends Message
{
    //--static class constants
    public static final int MAX_EMAIL_ADDRESS_LEN = 125;
    public static final int MIN_EMAIL_ADDRESS_LEN = 6;
    public static final String DEFAULT_EMAIL_ADDRESS = "(undefined)@(N/A).com";
  
    //--private member data
    private String fromAddress;
    private String toAddress;
  
    //--public class methods---
  
    //Default constructor for Email class. Sets email fromAddress and toAddress
    //to default values.
    public Email()
    {
        fromAddress = DEFAULT_EMAIL_ADDRESS;
        toAddress = DEFAULT_EMAIL_ADDRESS;
    }
  
    //Overloaded three parameter constructor for Email class.
   public Email(String message, String fromAddress, String toAddress)
    {
        super(message);
        if (!setFromAddress(fromAddress))
            this.fromAddress = DEFAULT_EMAIL_ADDRESS;
        if (!setToAddress(toAddress))
            this.toAddress = DEFAULT_EMAIL_ADDRESS;
    }
    //Mutator for fromAddress.
   public boolean setFromAddress(String addressTest)
    {
        if (!isValidEmailAddress(addressTest))
            return false;
        fromAddress = addressTest;
        return true;
    }
    //Mutator for toAddress.
   public boolean setToAddress(String addressTest)
    {
        if (!isValidEmailAddress(addressTest))
            return false;

        toAddress = addressTest;
        return true;
    }
    //Simple accessor for fromAddress. Returns fromAddress as a String.
    public String getFromAddress()
    {
        return fromAddress;
    }
    //Simple accessor for toAddress. Returns toAddress as a String
    public String getToAddress()
    {
        return toAddress;
    }
    //toString() functionality for Email class. public String toString()
    {
        String retString = super.toString();
        retString += "From: " + fromAddress + " " + "To: " +toAddress +" ";
      
        return retString;
    }
    //Private static validation helper for the Email class.
   private static boolean isValidEmailAddress(String addressTest)
    {
        if (addressTest.length() > MAX_EMAIL_ADDRESS_LEN ||
            addressTest.length() < MIN_EMAIL_ADDRESS_LEN ||
            addressTest.indexOf('@') == -1 ||
            addressTest.indexOf('.') == -1)
            return false;
      
        return true;
    }
}

class Shweet extends Message
{
    //--static class constants
    public static final int MAX_SHWITTER_ID_LENGTH = 15;
    public static final int MAX_SHWEET_LENGTH = 140;
    public static final String DEFAULT_USER_ID = "!invalid user!";
  
    //--private member data
    String fromID;
  
    //--public class methods--
  
    //Default constructor for class Shweet. Sets private member data fromID
    //to the default ID, which is a flag that the ID is actually invalid.
  
    public Shweet()
    {
        fromID = DEFAULT_USER_ID;
    }
    //Overloaded constructor for class Shweet.
   public Shweet(String message, String fromID)
    {
        super(message);
        setMessage(message);
        if (!setID(fromID))
            this.fromID = DEFAULT_USER_ID;
    }
  
    //Mutator for the fromID(Shweet ID).
   public boolean setID(String idTest)
    {
        if (!isValidShwitterID(idTest))
            return false;
        fromID = idTest;
        return true;
    }
    //Mutator for Shweet class messages.
   public boolean setMessage(String shweetTest)
    {
       if (!super.setMessage(shweetTest))
           return false;
       if (!isValidShweet(shweetTest))
           return false;
     
       super.setMessage(shweetTest);
       return true;
    }
    //Simple accessor for fromID. Returns fromID as a String.
    public String getID()
    {
        return fromID;
    }
    //toString() functionality for Shweet class. public String toString()
    {
        String retString = "Shweet: @" + fromID + " ";
        retString += super.toString() + " ";
      
        return retString;
    }

  
    //---private helper methods---
  
    //Checks for the validity of a Shweet by checking for its length compared
    //to the Shweet class constants. private boolean isValidShweet(String shweetTest)
    {
        if (shweetTest.length() > MAX_SHWEET_LENGTH)
            return false;
        return true;
    }
    //Checks for the validity of a shwitter ID by passing it as a String,
    private boolean isValidShwitterID(String idTest)
    {
        if (idTest.length() > MAX_SHWITTER_ID_LENGTH)
            return false;
        return stringHasOnlyAlphaOrNumOrUnderscore(idTest);
    }
  
    //Checks to see if a String has only alphanumeric characters or underscores.
    private boolean stringHasOnlyAlphaOrNumOrUnderscore(String testString)
    {
        for (int i = 0; i <testString.length(); i++)
        {
            if (!Character.isLetterOrDigit(testString.charAt(i)) &&
                testString.charAt(i) != '_')
                return false;
        }
        return true;
    }
  
}

sample output
---Tests of Base Class----


---Initial messages using toString():

Message 1:
(invalid message)
Message 2:
My life for Aiur!
Message 3:
(invalid message)

---Mutated msg1, msg3. Showing w/ toString():

Message 1:
Goodbye cruel world!
Message 2:
My life for Aiur!
Message 3:
IT IS GOOD TO BE A VALID MESSAGE!

---Testing message accessor:

Message 1:
Goodbye cruel world!

Message 2:
My life for Aiur!

Message 3:
IT IS GOOD TO BE A VALID MESSAGE!
---Testing message mutator:

Successfully mutated testMsg1
Testmsg2 mutate too long (expected)
Testmsg3 mutate too short (expected)


******END OF BASE CLASS TESTS*******
---Tests of Derived Class Email----

---Initial Emails using toString():

Email 1:
(invalid message)
From: (undefined)@(N/A).com
To: (undefined)@(N/A).com

Email 2:
Hello there
From: Cliff@Foothill.edu
To: JA@AOL.com

Email 3:
Invalid address here
From: Bob@Bob.com
To: (undefined)@(N/A).com


---Mutated emails.Showing w/ toString():

Email1 :
this is a new email message
From: (undefined)@(N/A).com
To: (undefined)@(N/A).com

Email2 :
Hello there
From: Cliff@Foothill.edu
To: JA@AOL.com

Email3 :
Invalid address here
From: Bob@Bob.com
To: email@email.email


---Testing derived class(Email) accessor:
Email1 :
(undefined)@(N/A).com
Email2 :
JA@AOL.com
Email3:
Invalid address here
---Testing message mutator:

Failed to mutate fromAddress email1
email2 mutate too long (expected)
Email3 mutate too short (expected)

Missing '@' character for email3 (expected)

******END OF EMAIL CLASS TESTS*******

---Tests of Derived Class Shweet----

---Initial Shweets using toString():

Shweet 1:
Shweet: @!invalid user!
(invalid message)

Shweet 2:
Shweet: @hardenMan
WOW I M A SHWEET


---Mutated Shweets.Showing w/ toString():

Shweet1 :
Shweet: @N0_SP4CES
Guacamole, we've got a shweet!

Shweet2 :
Shweet: @hardenMan
New valid shweet


---Testing derived class(Shweet) accessor:
shweet1 msg :
Guacamole, we've got a shweet!
shweet2 ID :
hardenMan
shweet1 ID:
N0_SP4CES

---Testing shweet mutator:

shweet1 too long (expected)

Successfully changed id shweet1 (expected)

Successfully changed shweet2 msg (expected)

invalid characters for shweet2 Id (expected)

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote