AP COMPUTER
SCIENCE
DEFINING CLASSES
OBJECTS AND CLASSES
⦿ An object is an entity that represents a bunch of related data and behaviors
◼ We have used these before: String, Scanner, ArrayList, …
⦿ A class defines a template for a type of object
◼ The Scanner class is a template for creating Scanner objects
◼ Like a blueprint for a house, not the house itself
⦿ Once we've defined a class, we can create
ENCAPSULATION AND
ABSTRACTION
⦿ Classes and objects are at the heart of
object-oriented programming, and provide two
key benefits:
◼ Encapsulation: putting related information together
and treating it as a single entity
We generally talk about a car, not an engine, transmission, battery, wheels, etc.
◼ Abstraction: distancing the details from the general
concepts
CLASS DEFINITION
⦿ Classes consist of three components:
◼ Methods
Provide class behavior
Defined just like we have been, except don’t use static
◼ Constructors
Special methods that define how to create instances of the class
◼ Fields
Store class state
Like variables whose scope is the entire class
Declared like we’re used to, but usually prefix with
CLASS DEFINITION
⦿ Classes are defined
using the class
keyword:
public class <class-name> {
<fields>
<constructors> <other methods>
}
⦿ Remember our
rules/conventions:
◼ Class names are like variable names:
Letters, digits, underscores only
Don't start with digit
◼ Class names begin with a capital letter
◼ Use another capital letter for each new word
DATA-ONLY CLASSES
⦿
The simplest classes contain only fields
⦿
These classes simply provide a way to group
several related pieces of data together
public class Fraction { public int numerator; public int denominator; }
◼ Notice that the variables here are public
DATA-ONLY CLASSES
⦿ The fields can be accessed using the same
notation as methods, but without parentheses:
frac.numerator = 5; frac.denominator = 7;
⦿ Simple classes automatically provide a default (no argument) constructor
DATA-ONLY CLASSES
public static Fraction multiply(Fraction frac1, Fraction frac2) { Fraction result = new Fraction();
result.numerator = frac1.numerator * frac2.numerator;
result.denominator = frac1.denominator * frac2.denominator; return reduce(result);
}
public static Fraction add(Fraction frac1, Fraction frac2) { Fraction result = new Fraction();
result.numerator = (frac1.numerator * frac2.denominator) + (frac2.numerator * frac1.denominator);
result.denominator = frac1.denominator * frac2.denominator; return reduce(result);
CLIENT PROGRAMS
⦿ When we define a class, it is not a runnable program
⦿ Instead, we write another Java file, called the
client program to use the class
◼ A class can have many clients, and a client can use many classes
◼ All the programs you have written so far have been clients of Java library classes
CLIENT PROGRAMS
public static void main(String[] args) { Scanner kb = new Scanner(System.in); Fraction frac = new Fraction();
System.out.println("Enter a fraction: "); String[] tokens = kb.nextLine().split("/"); frac.numerator = Integer.parseInt(tokens[0]); frac.denominator = Integer.parseInt(tokens[1]);
Fraction frac2 = new Fraction();
System.out.println("Enter a fraction: "); String[] tokens2 = kb.nextLine().split("/"); frac2.numerator = Integer.parseInt(tokens[0]); frac2.denominator = Integer.parseInt(tokens[1]);
DATA-ONLY CLASSES
⦿ Exercise 1: Define a simple class to represent a point in the
Cartesian (x-y) coordinate plane. Then write three static client methods: one to find the slope of a line containing two given points, one to find the midpoint of two points, and one to find the distance between two points. Finally, write a client
program that uses your static methods. Remember to use your point class, not raw numbers!
ACCESS CONTROL
⦿ We’ve been using public in a lot of places
⦿ public is a Java access specifier
◼ Others are private and protected
⦿ Access specifiers tell Java who should be able to see and use the class/method/variable we’re
defining
◼ public: can be seen/used by everyone anywhere
◼ private: can only be seen/used by the class itself
ACCESS CONTROL
⦿ Now that we’re defining classes, we’ll start using
private for some things
⦿ Like with variable names, there are no rules about this, just conventions
⦿ We’ll use the following conventions:
◼ Almost all fields will be private
◼ Almost all constructors will be public
◼ Methods will be public if other classes will want to use them, and private otherwise
ACCESS CONTROL
⦿
Since we want fields to be private, our
Fraction class should look like this:
public class Fraction {
private int numerator;
private int denominator; }
⦿
Once we do this, we can't access the field
directly anymore:
Fraction frac = new Fraction();
ACCESSOR (GETTER) METHODS
⦿ Instead, we use accessor methods to provide access to the data
⦿ Simple accessor methods typically have names of the form getVariable, take no arguments, and return the type of the field they are accessing
public int getNumerator() { return numerator;
}
⦿Using these methods provides a layer of
abstraction between the client and the data
MODIFIER (SETTER) METHODS
⦿ Modifier methods are the analog of getter methods
◼ They are used to set the value of a variable
⦿ Modifier methods typically have names of the form
setVariable, have a void return type, and take a single argument of the relevant type
public void setNumerator(int newNum) { numerator = newNum;
}
⦿ Sometimes, we will provide an accessor but no modifier (or, much less often, vice versa)
GETTERS/SETTERS
⦿ Exercise 1: Update your Cartesian coordinate class to use getters and setters. Change the client program accordingly.
⦿ Exercise 2: Modify your Cartesian coordinate class to use polar coordinates in the implementation (ask a neighbor if you don't know/remember polar). Do so in a way that does not require changing the client.
x = r cos(theta) y = r sin(theta)
CONSTRUCTORS
⦿ Objects are created in Java using constructors
⦿ Constructors are like other methods, but have two special properties:
◼ Their name is the same as the name of the class
◼ They do not have a return type
The implicit return type is the class itself (sort of)
⦿ Constructors cannot be invoked directly-- we use the new keyword:
CONSTRUCTORS
⦿ Constructors are defined just like other methods, but with no return type or value
⦿ Constructors can be overloaded, just like other methods
public Fraction(int numerator, int denominator) { numerator = numerator;
denominator = denominator; }
public Fraction(double decimal) { // math to convert to fraction }
THIS
KEYWORD
⦿ We can access the current object by using the
this keyword
◼ In a constructor, this is the object being created
◼ In any other method, this is the target of the method call
public Fraction(int numerator, int denominator) {
this.numerator = numerator;
COMMON CONSTRUCTOR BUGS
⦿ Re-declaring fields as local variables
("shadowing"):
public Fraction(int num, int denom) { int numerator = num; int denominator = denom; }
◼ This declares local
variables with the same name as the fields,
rather than storing values into the fields.
⦿ Accidentally giving the constructor a return type:
public void Fraction(int numerator, int denominator) { this.numerator = numerator;
this.denominator = denominator; }
◼ This is actually not a constructor, but a
OTHER METHODS
⦿ We can also provide any other methods we might want or that might be useful
⦿ These other methods will use our variables, and can possibly call other methods
public Fraction reciprocal() {
return new Fraction(denominator, numerator); }
public Fraction divideBy(Fraction other) { Fraction recip = other.reciprocal();
SPECIAL METHODS
⦿ There are two "special" methods that many classes define
◼ equals() is used to compare objects Since we can't use ==
◼ toString() allows clients to print out objects using System.out.print() and System.out.println()
⦿ If you define these methods properly, they will get automatically picked up where needed
EQUALS()
public boolean equals(<class> other)
⦿ Defines how objects are compared for equality
⦿ A common way to do this is to compare field-by-field
◼ If any field isn't the same, the objects aren't
⦿
It is up to you, as the class author, to define
what constitutes "equal"
TOSTRING()
public String toString()
⦿
Defines the String representation of the class
⦿
Returns
a String-- does not print!
⦿
Is automatically called when you use an
object in
System.out.print()
or
OTHER METHODS
⦿ Exercise 1: Add the following methods to your Point
class. Then, modify your client program to use these new instance methods instead of the previously written client methods.
◼ double distanceTo(Point other)
◼ double slopeTo(Point other)
◼ Point midpointTo(Point other)
◼ double distanceFromCenter()
◼ int quadrant()
⦿ Exercise 2: Implement appropriate versions of equals()
CLASS METHODS
⦿ So far, all the methods we’ve defined have been instance
methods
◼ The method corresponds to a particular instance of the class
⦿ There is another type of method, called a class method
◼ Class methods do not relate to a particular instance– they
belong to the class as a whole
⦿ Class methods are declared just like instance methods except:
◼ They are preceded by the static keyword
◼ They cannot call any instance methods or access any instance
CLASS VARIABLES
⦿
Class variables, sometimes called static
fields, are variables whose value is shared by
every instance of the class
⦿
These fields behave just like normal fields,
except changes by one instance are seen by
others
⦿
These fields are declared with the
static
COUNTING INSTANCES
⦿ One common use of static variables and methods is to count the number of instances of a class that have been created
◼ These can be used to, for example, assign unique id #s
public class Fraction {
private static int numFracs = 0;
public static int getNumFracs() { return numFracs; } public Fraction(int numerator, int denominator) { numFracs++;
... }
COUNTING INSTANCES
public static void main(String[] args) {
System.out.println(Fraction.getNumFracs()); // 0
Fraction frac1 = new Fraction(1, 2);
System.out.println(Fraction.getNumFracs()); // 1
Fraction frac1 = new Fraction(3, 4); Fraction frac1 = new Fraction(5, 3);
System.out.println(Fraction.getNumFracs()); // 3
DEFINING CLASSES
⦿ Exercise: Define a class to represent a high school course. Your class should include methods to
provide the following information about the course:
Course title Teacher name
Course id # (unique and assigned automatically) Is a particular student enrolled in the course?
Bonus: Does this course have the same teacher as another
course?
Bonus: How many total courses have been created?
◼ Think about what variables, methods, and constructors