Creating Classes
Creating a class is the most basic thing you need to know to do on the second Collegeboard FRQ. This is means that you should be able to define a class with the required attributes and methods within a single unit to make the code more organized and modular.
In some AP CSA Exam question you may need to create the entire class, but in others you may be given the class and told to fill it in with methods and variables.
2023 Example FRQ
Attributes:
The Sign class has two private attributes: message
and lineWidth
. These attributes store the message to be displayed on the sign and the width of each line, respectively.
Constructor:
The class includes a constructor that initializes the message
and lineWidth
attributes when a Sign object is created. This constructor follows POJO principles by accepting parameters to set the initial state of the object.
Methods:
numberOfLines()
: This method calculates the number of lines needed to display the message on the sign based on the line width. It ensures that the entire message is displayed, even if it spans multiple lines. getLines()
: This method formats the message into lines separated by semicolons, ensuring that each line respects the specified line width. Main
Method: The main method demonstrates the usage of the Sign
class by creating instances of Sign objects and printing information about each sign, including the message, number of lines, and formatted lines.
public class Sign {
// attributes defined
private String message;
private int lineWidth;
public Sign(String message, int lineWidth) { // Constructor using POJO principles
this.message = message;
this.lineWidth = lineWidth;
}
public int numberOfLines() { // method used to read num of lines
int lines = message.length() / lineWidth;
if (message.length() % lineWidth > 0)
lines++;
return lines;
}
public String getLines() { // method used to get num of lines
if (message.length() == 0)
return null;
String lines = "";
String messageRemaining = message;
while (messageRemaining.length() > lineWidth) {
lines += messageRemaining.substring(0, lineWidth);
lines += ";";
messageRemaining = messageRemaining.substring(lineWidth);
}
lines += messageRemaining;
return lines;
}
public static void main(String[] args) {
// Example of using the Sign class without collections
Sign sign1 = new Sign("Hey guys this is an example", 20); // Create Sign objects
Sign sign2 = new Sign("of a POJO", 15);
// Print information for each Sign object
System.out.println("Message: " + sign1.message);
System.out.println("Number of Lines: " + sign1.numberOfLines());
System.out.println("Lines:");
System.out.println(sign1.getLines());
System.out.println();
System.out.println("Message: " + sign2.message);
System.out.println("Number of Lines: " + sign2.numberOfLines());
System.out.println("Lines:");
System.out.println(sign2.getLines());
}
}
Sign.main(null);
1
2
3
4
5
6
7
8
9
Message: Hey guys this is an example
Number of Lines: 2
Lines:
Hey guys this is an ;example
Message: of a POJO
Number of Lines: 1
Lines:
of a POJO
Tips For Exam
- You typically want to follow all naming conventions when doing the AP Exam.
- You can use personalized variables unless otherwise noted.
- Methods in classes should be specified as instructed by the question.
- The methods you create can vary in how they complete the specified task, they just need to execute the task correctly.
Implementing Methods
Data Manipulation:
Methods in POJOs can perform various operations on the data they encapsulate. These operations can include calculations, transformations, validations, or any other logic necessary to modify the data according to the requirements of the application.
Behavioral Methods:
POJOs may contain methods that represent behaviors or actions associated with the object. These methods are not necessarily related to data manipulation but instead define the behavior of the object in response to certain actions or events.
Validation:
Methods can enforce data validation rules to ensure that the data stored within the POJO remains valid and consistent. For example, a method can validate whether a certain attribute falls within a specific range or meets certain criteria before allowing it to be modified.
Data Transformation:
Methods can transform the data stored within a POJO into different formats or representations. This transformation might involve converting data types, formatting strings, or applying business rules to the data.
Add on note: One such example is the toString()
method
Complex Operations:
POJO methods can encapsulate complex operations that involve multiple steps or computations. By encapsulating such operations within methods, the complexity of the implementation is hidden from the external code, leading to cleaner and more maintainable code.
Interaction with Other Objects:
Methods in POJOs can interact with other objects, either within the same class hierarchy or external to the class. This interaction might involve invoking methods on other objects, passing data between objects, or collaborating with other objects to achieve a certain behavior or functionality.
public class Sign {
// attributes defined
private String message; // Attribute to store the message to be displayed on the sign
private int lineWidth; // Attribute to store the width of each line on the sign
// Constructor using POJO principles
public Sign(String message, int lineWidth) {
this.message = message; // Initialize the message attribute with the provided message
this.lineWidth = lineWidth; // Initialize the lineWidth attribute with the provided lineWidth
}
// Method to calculate the number of lines needed to display the message on the sign
public int numberOfLines() {
int lines = message.length() / lineWidth; // Calculate the number of full lines
if (message.length() % lineWidth > 0) // Check if there are remaining characters
lines++; // Increment the number of lines if there are remaining characters
return lines; // Return the total number of lines
}
// Method to format the message into lines separated by semicolons
public String getLines() {
if (message.length() == 0) // Check if the message is empty
return null; // If the message is empty, return null
String lines = ""; // Initialize a string to store the formatted lines
String messageRemaining = message; // Initialize a string to store the remaining message
// Loop until there is no message remaining
while (messageRemaining.length() > lineWidth) {
lines += messageRemaining.substring(0, lineWidth); // Add a line of width lineWidth to the lines string
lines += ";"; // Add a semicolon to separate lines
messageRemaining = messageRemaining.substring(lineWidth); // Remove the processed characters from the message
}
lines += messageRemaining; // Add the remaining message as the last line
return lines; // Return the formatted lines
}
public static void main(String[] args) {
// Example of using the Sign class without collections
Sign sign1 = new Sign("Hey guys this is an example", 20); // Create Sign objects
Sign sign2 = new Sign("of a POJO", 15);
// Print information for each Sign object
System.out.println("Message: " + sign1.message); // Print the message of sign1
System.out.println("Number of Lines: " + sign1.numberOfLines()); // Print the number of lines for sign1
System.out.println("Lines:");
System.out.println(sign1.getLines()); // Print the formatted lines for sign1
System.out.println();
System.out.println("Message: " + sign2.message); // Print the message of sign2
System.out.println("Number of Lines: " + sign2.numberOfLines()); // Print the number of lines for sign2
System.out.println("Lines:");
System.out.println(sign2.getLines()); // Print the formatted lines for sign2
}
}
Sign.main(null);
1
2
3
4
5
6
7
8
9
Message: Hey guys this is an example
Number of Lines: 2
Lines:
Hey guys this is an ;example
Message: of a POJO
Number of Lines: 1
Lines:
of a POJO
Tips for Exam:
- Make sure that all of your method signatures are correct and that you understand them well. This would include the return type, method name, parameters, and access modifiers.
- Make sure to follow the naming convention assigned by Collegeboard.
- Try to make the methods as efficient as possible without using built in methods than may cut out pieces of code.
- If exceptions need to be tested, make sure you add them.
Inheritance and Polymorphism
Inheritance allows POJOs to inherit attributes and methods from parent classes, allowing for code reuse and efficiency. Polymorphism allows objects of different classes (including subclasses) to be treated uniformly through a common interface, leading to flexibility in the code.
public class Displayable {
protected String message;
protected int lineWidth;
public Displayable(String message, int lineWidth) { // constructor using POJO
this.message = message;
this.lineWidth = lineWidth;
}
public int numberOfLines() { // method to read num of lines
int lines = message.length() / lineWidth;
if (message.length() % lineWidth > 0)
lines++;
return lines;
}
public String getLines() { // method to get the lines
if (message.length() == 0)
return null;
String lines = "";
String messageRemaining = message;
while (messageRemaining.length() > lineWidth) {
lines += messageRemaining.substring(0, lineWidth);
lines += ";";
messageRemaining = messageRemaining.substring(lineWidth);
}
lines += messageRemaining;
return lines;
}
}
// Subclass Sign inherits from Displayable
public class Sign extends Displayable {
public Sign(String message, int lineWidth) { // constructor for creating the sigh with the message
super(message, lineWidth);
}
}
// Another subclass AdvertisementSign also inherits from Displayable
public class AdvertisementSign extends Displayable {
public AdvertisementSign(String message, int lineWidth) { // another constructor
super(message, lineWidth);
}
// Additional method specific to AdvertisementSign
public void displayAdvertisement() {
System.out.println("Advertisement: " + message);
}
}
public class Main {
public static void main(String[] args) {
// Create objects of Sign and AdvertisementSign
Displayable sign1 = new Sign("Hey guys this is an example", 20);
Displayable adSign = new AdvertisementSign("50% off all items", 25);
// Print information for each Displayable object
System.out.println("Message: " + sign1.message);
System.out.println("Number of Lines: " + sign1.numberOfLines());
System.out.println("Lines:");
System.out.println(sign1.getLines());
System.out.println();
System.out.println("Message: " + adSign.message);
System.out.println("Number of Lines: " + adSign.numberOfLines());
System.out.println("Lines:");
System.out.println(adSign.getLines());
// Demonstrate polymorphism by calling the displayAdvertisement() method
if (adSign instanceof AdvertisementSign) {
((AdvertisementSign) adSign).displayAdvertisement(); // AdvertisementSign class is able to display messages differently
}
}
}
Main.main(null);
1
2
3
4
5
6
7
8
9
10
Message: Hey guys this is an example
Number of Lines: 2
Lines:
Hey guys this is an ;example
Message: 50% off all items
Number of Lines: 1
Lines:
50% off all items
Advertisement: 50% off all items
Tips for Exam:
- Make sure to know how these work. Although you may not be asked to write everything from scratch, some parts may ask you to implement these ideas.
- Know the scopes of your variables. Pay attention to access of different variables as you move across classes.
Working with Collections
During the AP CSA Exam, you might come across a question asking for you to use a type of collection or objects like a ArrayList or Strings and manage a group of POJOs
POJOs also help to reduce the number of times that something is instantiated, allowing for a more organized and possibly simpler code
POJO are really effective especially when it comes to object oriented programming
// Example is from the AP CSA FRQ 2023, Question 2 but modified a little
import java.util.ArrayList;
public class Sign {
private String message;
private int lineWidth;
public Sign(String message, int lineWidth) { // Constructors using POJOs
this.message = message;
this.lineWidth = lineWidth;
}
public int numberOfLines() {
int lines = message.length() / lineWidth;
if (message.length() % lineWidth > 0)
lines++;
return lines;
}
public String getLines() {
if (message.length() == 0)
return null;
String lines = "";
String messageRemaining = message;
while (messageRemaining.length() > lineWidth) {
lines += messageRemaining.substring(0, lineWidth);
lines += ";";
messageRemaining = messageRemaining.substring(lineWidth);
}
lines += messageRemaining;
return lines;
}
public static void main(String[] args) { // Example of managing a collection of Sign objects
ArrayList<Sign> signs = new ArrayList<>();
signs.add(new Sign("Hey guys this is an example", 20)); // Create and add Sign objects to the collection
signs.add(new Sign("of a POJO in a collection", 15));
for (Sign sign : signs) { // Print information for each Sign object
System.out.println("Message: " + sign.message);
System.out.println("Number of Lines: " + sign.numberOfLines());
System.out.println("Lines:");
System.out.println(sign.getLines());
System.out.println();
}
}
}
Sign.main(null)
1
2
3
4
5
6
7
8
9
Message: Hey guys this is an example
Number of Lines: 2
Lines:
Hey guys this is an ;example
Message: of a POJO in a collection
Number of Lines: 2
Lines:
of a POJO in a ;collection
One important thing to note:
- POJOs aren’t always required for the CSA FRQ and sometimes aren’t even in the requirements for the question, however, it is something that you should know and should have as one of you different techniques to approaching code especially when it comes to working code using OOP and also serves a good way to understand/show understanding of Java better and also, the AP Exam always accepts the initialization of variable through POJO and its a good habit to have
Serialization and Deserialization (not really a focus on the AP Exam)
Serialization and Deserialization is the conversion of an object into a more storable or transmittable form of data (serialization) and then converting those objects back to a Java Objects
Examples would be: JSON and XML
Here is a diagram showing a general idea of how it works:
While not on the AP Exam, they are a very important part of Java programming and a basic understanding can help alot
Encapsulation and Access Control
- One of the things that the AP Exam commonly makes sure that you know and have during the FRQ section in teh encapsulation and access control
Encapsulation:
Encapsulation is one of the 4 main OOP concepts that the AP CSA Exams tests on (the others are inheritance, polymorphism and abstraction)
Encapsulation is done through using classes and access modifiers
Ways you might be asked to do this or could see this is through defining private fields and providing setters and getters and other public methods to access and modify those fields
Encapsulation allows for protection against other parts of the program by preventing them to modify it
Access Control
Determines what is visible and what isn’t in a program and protects data integrity
The exam might ask questions that will cause you to decide and apply the right access modifiers (private, public) and the MC section might even test your ability to determine which ones are incorrect and why
Declaring the right Access Controls can account for 4/10 of the points on the FRQ and so it is very important that you understand what and why each access control is used
Example:
import java.util.ArrayList;
public class Sign {
private String message; // private variables, encapsulates the 'Sign' object, hiding it from other classes
private int lineWidth;
public Sign(String message, int lineWidth) { // Constructors using POJOs
this.message = message;
this.lineWidth = lineWidth;
}
public int numberOfLines() { // public method that provides controlled access to the private data members
int lines = message.length() / lineWidth;
if (message.length() % lineWidth > 0)
lines++;
return lines;
}
public String getLines() { // public method that provides controlled access to the private data members
if (message.length() == 0)
return null;
String lines = "";
String messageRemaining = message;
while (messageRemaining.length() > lineWidth) {
lines += messageRemaining.substring(0, lineWidth);
lines += ";";
messageRemaining = messageRemaining.substring(lineWidth);
}
lines += messageRemaining;
return lines;
}
}
Question 1 - Pojos and Access Control:
Situation: The school librarian wants to create a program that stores all of the books within the library in a database and is used to manage their inventory of books available to the students. You decided to put your amazing code skills to work and help out the librarian!
a. Describe the key differences between the private and public access controllers and how it affects a POJO A public and private class are different, as public objects are accessible by all other things in the program, while a private object is confined to it’s local class or method.
b. Identify a scenario when you would use the private vs. public access controllers that isn’t the one given in the scenario above You would use a private access controller when you want to restrict access to a variable or method to only the class that it is in. You would use a public access controller when you want to allow access to a variable or method to all classes in the program.
c. Create a Book class that represents the following attributes about a book: title, author, date published, person holding the book and make sure that the objects are using a POJO, the proper getters and setters and are secure from any other modifications that the program makes later to the objects
public class Book {
private String title;
private String author;
private String datePublished;
private String personHoldingBook;
public Book(String title, String author, String datePublished, String personHoldingBook) {
this.title = title;
this.author = author;
this.datePublished = datePublished;
this.personHoldingBook = personHoldingBook;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getDatePublished() {
return datePublished;
}
public void setDatePublished(String datePublished) {
this.datePublished = datePublished;
}
public String getPersonHoldingBook() {
return personHoldingBook;
}
public void setPersonHoldingBook(String personHoldingBook) {
this.personHoldingBook = personHoldingBook;
}
@Override
public String toString() {
return "Book{" +
"title='" + title + '\'' +
", author='" + author + '\'' +
", datePublished='" + datePublished + '\'' +
", personHoldingBook='" + personHoldingBook + '\'' +
'}';
}
public static void main(String[] args) {
Book book = new Book("Book1", "Author1", "Thursday March 28th", "Library");
System.out.println(book);
}
}
Book.main(null);
1
Book{title='Book1', author='Author1', datePublished='Thursday March 28th', personHoldingBook='Library'}