Chapter 1 (intro to OOP, getting started with Java, numerical data) and Chapter 2 (programmer-defined classes, this, overloading). Every slide is covered, including the ones that were only pictures and diagrams.
✎ Select any text to add your own highlights. They're saved and only you can see them.
how we got to OOP
anatomy of an object
the cookie-cutter picture
one class (cutter) can stamp out many objects (cookies) → "an object is an instance of a class"
<Object Name> : <Class Name>, shows which class the object is an instance of, e.g. SV198 : BankAccount.the three icons
three message diagrams from the slides
① message deposit with argument 250.00 is sent to object SV198 (instance method, nothing returned)
② ask for the current balance of this particular account → the balance is returned
③ class method: sent to the class itself (not underlined), returns the max possible speed for all MobileRobot objects
sample class & instance data values
the dashed lines = instance-of relationship · one shared copy of minimum balance in the class · all 3 objects have the same instance data value (current balance) but different amounts
no class icon drawn?
sample inheritance
inheritance hierarchy
the 5 stages, in order
mnemonic: A D C T O → "A Dog Can Take Orders"
| # | Advantage | Why |
|---|---|---|
| 1 | Improved software-development productivity | modular (separation of duties), extensible (objects extended with new attributes & behaviours), reused within and across applications |
| 2 | Improved software maintainability | easier to maintain; modular design means part of the system can be updated without large-scale changes |
| 3 | Faster development | reuse → faster development; rich libraries of objects; project code reusable in future projects |
| 4 | Lower cost of development | reuse lowers cost; more effort goes into OO analysis & design, which lowers the overall cost |
| 5 | Higher-quality software | faster + cheaper → more time & resources for verification (quality still depends on team experience) |
| VALID | INVALID | why invalid |
|---|---|---|
MyFirstApplication | 45678 | starts with a digit |
FunTime | Sample Program | contains a space |
DEFAULT_VALUE | hello,there | comma not allowed |
standard naming convention
Robotclass name → Capital firstrobotobject name → small firstmultiple words → capitalise the first letter of every word, except the first word if it's an object name
MyMainWindowclassmyMainWindowobject (NOT mymainwindow)Customer customer; // 1. declaration customer = new Customer( ); // 2. creation
what happens in memory
Student john = new Student(); instead of Student john; + john = new Student();name vs objects: calling new twice
Customer customer; customer = new Customer( ); // first object customer = new Customer( ); // second object
the second new makes customer point to the new object → reference to the first Customer object is lost
<object>.<method>(<arguments>); e.g. account.deposit(200.0); · student.setName("john"); · car1.startEngine();/* The program is
expected to print Java */ // comment
public class Main{ // class
String attribute;
public void display() { // method
System.out.println(attribute);}
public static void main(String[] args) {
Main obj = new Main();
// obj.attribute = "Hello"; This line is commented
obj.attribute = "Java";
obj.display();
}
}| Type | Markers | Use |
|---|---|---|
| Multiline | /* … */ | comment across several lines |
| Single line | // … | everything after // on that line |
| javadoc | /** … */ | documentation comment, e.g. describing a class ("This class provides basic clock functions…") |
/* /* /* This is a comment */ */ <-- Error!
Comments do not nest. The first */ closes the comment, so the inner /* markers are just part of the comment text.
The leftover */ gives "Error: No matching beginning marker."
import syntax
importkeyword<package name>package that contains the class. <class name>class to import (* = all); e.g. dorm.Resident; · import javax.swing.JFrame; · import java.util.*; · import com.drcaffeine.simplegui.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String S;
Scanner in = new Scanner(System.in);
System.out.println("Enter a string");
S = in.nextLine();
System.out.println("You enter a string " + S);
}}| Standard class | Package | Used for |
|---|---|---|
Scanner | java.util | keyboard input |
String | java.lang | text (auto-imported) |
Date | java.util | current date & time |
SimpleDateFormat | java.text | formatting dates |
System.out is an instance of the PrintStream class, a simple way to show results on the console window (its look depends on the Java tool you use).System.out.print("How do you do? ");
System.out.print("My name is ");
System.out.print("Jon Java. ");System.out.println("How do you do? ");
System.out.println("My name is ");
System.out.println("Jon Java. ");String is an object
String name; // 1
name = new String("Jon Java"); // 21 = identifier name declared, space allocated · 2 = String object created, name refers to it
Indexing: the position (index) of the first character is 0.
charAt(index)
String a = "Expresso"; → a.charAt(3) gives r · a.length() gives 8 (last index = length − 1)
| Method | Returns | Examples |
|---|---|---|
str.length() | number of characters in str | "programming" → 11 · "Hello" → 5 · "Java" → 4 · "" (empty) → 0 · " " (one space) → 1 |
str.indexOf(substr) | first position where substr occurs; −1 if not found; case-sensitive | "programming".indexOf("gram") → 3 |
+ (concatenation) | joins strings | see below |
str = "I Love Java and Java loves me.";
str.indexOf("J") | 7 | first J |
str.indexOf("love") | 21 | lowercase "love" is inside "loves", not "Love" |
str.indexOf("ove") | 3 | "ove" is found in "Love" |
str.indexOf("Me") | −1 | "Me" not found (case-sensitive, text has "me") |
| str1 = "Jon"; str2 = "Java"; | Result |
|---|---|
str1 + str2 | "JonJava" (no space added!) |
str1 + " " + str2 | "Jon Java" |
str2 + ", " + str1 | "Java, Jon" |
"Are you " + str1 + "?" | "Are you Jon?" |
import java.util.*;
//import java.util.Date;
//import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Date today;
today = new Date( );
System.out.println(today);
}
}import java.util.Date;
import java.text.SimpleDateFormat;
...
Date today = new Date( );
SimpleDateFormat sdf1, sdf2;
sdf1 = new SimpleDateFormat("MM/dd/yy");
sdf2 = new SimpleDateFormat("MMMM dd, yyyy");
String a = sdf1.format(today);
String b = sdf2.format(today);
System.out.println(a + "\n" + b);java.util.* imports all classes in java.util (so both Date and Scanner).MM = month number · MMMM = full month name · dd = day · yy / yyyy = 2- / 4-digit year.sdf1.format(today)) and it returns the date as a String.System.in (the keyboard).input flow
import java.util.Scanner;Scanner in = new Scanner(System.in);name = in.nextLine();import java.util.Scanner;
public class Main {
public static void main(String args[]) {
String name;
Scanner in = new Scanner(System.in);
name = in.nextLine();
System.out.println("Hello there, " + name);
System.out.println("Welcome to Java");
}
}x + y we must declare their data type: int x, y; or int x; int y;int i, j, k; · float numberOne, numberTwo; · long bigInteger; · double bigNumber;int count = 10, height = 34;| Type | Content | Default | Minimum | Maximum |
|---|---|---|---|---|
byte | Integer | 0 | −128 | 127 |
short | Integer | 0 | −32768 | 32767 |
int | Integer | 0 | −2147483648 | 2147483647 |
long | Integer | 0 | −9223372036854775808 | 9223372036854775807 |
float | Real | 0.0 | −3.40282347E+38 | 3.40282347E+38 |
double | Real | 0.0 | −1.79769313486231570E+308 | 1.79769313486231570E+308 |
precision ladder (low → high)
long a = 323456789098765L; System.out.println(a);
E+38 means × 1038. So 3.40282347E+38 = 340,282,347 followed by 30 zeros.
A big whole number literal needs L at the end to be a long.
<variable> = <expression>; e.g. sum = firstNumber + secondNumber; · avg = (one + two + three) / 3.0;| Operation | Operator | Example | Value (x = 10, y = 7, z = 2.5) |
|---|---|---|---|
| Addition | + | x + y | 17 |
| Subtraction | - | x - y | 3 |
| Multiplication | * | x * y | 70 |
| Division | / | x / yx / z | 1 (not 1.429!) 4.0 |
| Modulo (remainder) | % | x % y | 3 |
int / int is integer division: the fractional part is truncated (10 / 7 = 1). If one operand is real (x / z) you get a real answer (4.0). Use a DecimalFormat object to format numerical output.The modulo operator returns the remainder of a division. It works with real numbers too, but is mostly used with integers.
| Modulo | Result |
|---|---|
23 % 5 | 3 |
23 % 25 | 23 |
16 % 2 | 0 |
x + 3 * y → x is added to 3*y (multiply first).evaluation order: high → low
( )innermost first · same level → left to right- +unary minus / plus* / %left to right+ -evaluated last · left to rightx is float and y is int, x * y is a float.casting decision flow
double x = 3 + 5; → 8.0int x = 3.5;(float) x / 3 · (int) (x / y * 3.0)Implicit: double x = 3 + 5; → 3 + 5 is int 8, promoted to 8.0 (double) before being assigned.
int x = 3.5; → error: a higher precision value cannot be assigned to a lower precision variable.
Explicit: prefix the operand with the type, syntax ( <data type> ) <expression>
(float) x / 3 → cast x to float, then divide by 3(int) (x / y * 3.0) → cast the result of the whole expression to intint x = 10; float y; y = (float) x / 3; System.out.println(y);
final declares a constant: final double PI = 3.14159; · final int MONTH_IN_YEAR = 12;final int x = 10; x = 20; // not allowed int y; y = x / 5; System.out.println(y);
int x = 10; x = 20; // fine int y; y = x / 5; System.out.println(y);
int num = 15;
System.out.print(num); //print a variable
System.out.print(" "); //print a string
System.out.print(10); //print a constantimport java.text.DecimalFormat;) to format numerical output.new DecimalFormat("0.000") → three decimal places (rounded).String.format("%.3f", num)double num = 123.45789345;
DecimalFormat df = new DecimalFormat("0.000");
System.out.println(num);
System.out.print(df.format(num));double num = 123.45789345;
String formatted = String.format("%.3f", num);
System.out.println(formatted);sample program Ch3Circle → Ch3Circle3
final double PI = 3.14159;
double radius, area, circumference;
radius = 2.35;
area = PI * radius * radius;
circumference = 2.0 * PI * radius;
System.out.println("Given Radius: " + radius);
System.out.println("Area: " + area);
System.out.println("Circumference: " + circumference);import java.text.*;
final double PI = 3.14159;
final String TAB = "\t";
final String NEWLINE = "\n";
DecimalFormat df = new DecimalFormat("0.000");
radius = 2.35;
...
System.out.println(
"Given Radius: " + TAB + df.format(radius) + NEWLINE +
"Area: " + TAB + df.format(area) + NEWLINE +
"Circumference: " + TAB + df.format(circumference));shows: radius value set · usage of constants (PI, TAB, NEWLINE) · usage of control characters \t (tab) and \n (new line) · formatted to 3 d.p.
Scanner scanner = new Scanner(System.in);
int age;
System.out.print("Enter your age: ");
age = scanner.nextInt();| Method | Example |
|---|---|
nextByte() | byte b = scanner.nextByte(); |
nextDouble() | double d = scanner.nextDouble(); |
nextFloat() | float f = scanner.nextFloat(); |
nextInt() | int i = scanner.nextInt(); |
nextLong() | long l = scanner.nextLong(); |
nextShort() | short s = scanner.nextShort(); |
nextLine() | String str = scanner.nextLine(); |
Math.method().(1.0 / 2.0) * Math.sin( x - Math.PI / Math.sqrt(y) )| Method | Description |
|---|---|
exp(a) | natural number e raised to the power of a |
log(a) | natural logarithm (base e) of a |
floor(a) | largest whole number ≤ a |
max(a,b) | the larger of a and b |
pow(a,b) | a raised to the power of b |
sqrt(a) | square root of a |
sin(a) | sine of a (all trig functions use radians) |
Math.random also works but is harder to use.)nextInt method.import java.util.Random;
public class Main {
public static void main(String[] args) {
Random ran = new Random();
int num = ran.nextInt(6);
System.out.println(num);
}
}random.nextInt() → any int.
ran.nextInt(6) → 0 to 5 (not 6!).
For a die use ran.nextInt(6) + 1 → 1 to 6. General: nextInt(MAX − MIN + 1) + MIN.
class BicycleRegistration {
public static void main(String[] args) {
Bicycle bike1, bike2;
String owner1, owner2;
bike1 = new Bicycle( );
bike1.setOwnerName("Adam Smith");
bike2 = new Bicycle( );
bike2.setOwnerName("Ben Jones");
owner1 = bike1.getOwnerName( );
owner2 = bike2.getOwnerName( );
System.out.println(owner1 + " owns a bicycle.");
System.out.println(owner2 + " also owns a bicycle.");
}
}class Bicycle {
// Data Member
private String ownerName;
//Constructor: Initialises the data member
public void Bicycle( ) {
ownerName = "Unknown";
}
//Returns the name of this bicycle's owner
public String getOwnerName( ) {
return ownerName;
}
//Assigns the name of this bicycle's owner
public void setOwnerName(String name) {
ownerName = name;
}
}public void Bicycle( ) as the constructor, but a real constructor has NO return type. With void it becomes an ordinary method that never runs automatically (see Kitty example 2 in 3.6). The correct form is public Bicycle( ) { … }.Once the Bicycle class is defined, we can create multiple instances; each has its own copy of ownerName.
A a = new A();
for (int i = 0; i < 10; i++) {
String keyedinname = scanner.nextLine();
a.setname(keyedinname);
}1 object created → its name is overwritten 10 times on the SAME object
for (int i = 0; i < 10; i++) {
A a = new A();
String keyedinname = scanner.nextLine();
a.setname(keyedinname);
}a NEW object every iteration → 10 objects in total
class diagram for Bicycle
method listing: list the name and the data type of any argument passed to the method
template for a class definition
class Class Name {}data member declaration
privatemodifiersStringdata typeownerNamename; <modifiers> <data type> <name>; · only one modifier in this example
method declaration
publicmodifiervoidreturn typesetOwnerNamemethod name( String name )parameter{ ownerName = name; }statements<modifier> <return type> <method name> ( <parameters> ) { <statements> }
void → a method that does not return a value (e.g. setOwnerName).getOwnerName() returns the value of instance variable ownerName, which was declared as String, so its return type is String.return <expression>;int, you can return int, short or byte.public <class name> ( <parameters> ) { <statements> }. <class name> = the class this constructor belongs to.constructor anatomy
publicmodifierBicycleclass name( )parameter{ ownerName = "Unassigned"; }statementsexample 1: who makes the constructor?
public class Kitty{
public static void main(String []args){
Kitty myKitty = new Kitty( );}
}public class Kitty{
public Kitty(){
//no need this constructor
}
public static void main(String []args){
Kitty myKitty = new Kitty( ); }
}example 2: constructor vs method with the same name
public class Kitty{
public Kitty(String name){
System.out.println("Passed Name is :" + name);
}
public static void main(String []args){
Kitty myKitty = new Kitty("molly");
}
}public class Kitty{
String name;
public void Kitty(){
System.out.println("Passed Name is :" + name);
}
public static void main(String []args){
Kitty myKitty = new Kitty( );
myKitty.name = "molly";
myKitty.Kitty();
}
}void and Kitty() stops being a constructor. It's a normal method that you must call yourself (myKitty.Kitty()).class SecondMain {
public static void main(String[] args) {
Bicycle bike;
Account acct;
String myName = "Jon Java";
bike = new Bicycle( );
bike.setOwnerName(myName);
acct = new Account( );
acct.setOwnerName(myName);
acct.setInitialBalance(250.00);
acct.add(25.00);
acct.deduct(50);
System.out.println(bike.getOwnerName() + " owns a bicycle and");
System.out.println("has $ " + acct.getCurrentBalance() +
" left in the bank");
}
}class Account {
private String ownerName;
private double balance;
public Account( ) {
ownerName = "Unassigned";
balance = 0.0;
}
public void add(double amt) {
balance = balance + amt; }
public void deduct(double amt) {
balance = balance - amt; }
public double getCurrentBalance( ) {
return balance; }
public String getOwnerName( ) {
return ownerName; }
public void setInitialBalance(double bal) {
balance = bal; }
public void setOwnerName(String name) {
ownerName = name; }
}250.00 + 25.00 − 50 = 225.0
class Demo {
public void compute(int i, int j, double x) {
double result = i + j + x;
System.out.println("Computation result: " + result);
}
}
class Account {
private double balance = 0.0;
public void add(double amt) {
balance = balance + amt;
System.out.println("Current Balance: " + balance);
}
}
public class Main {
public static void main(String[] args) {
Account acct = new Account();
acct.add(400);
Demo demo = new Demo();
int i = 5;
int k = 14;
demo.compute(i, k, 20);
}
}main is public, and the file is named after it (Main.java). Passing int 400 to a double parameter prints 400.0, and 5 + 14 + 20.0 = 39.0.acct.add(400); → 400 is the argument.add(double amt) → amt is the parameter.matching them up
i (5)k (14)20int iint jdouble xdemo.compute(i, k, 20) → compute(int i, int j, double x) · 3 arguments ↔ 3 parameters
① The number of arguments and parameters must be the same.
② They are paired left to right.
③ Each pair must be assignment-compatible. You can't pass a double argument to an int parameter.
public and private set the accessibility of data members and methods.accessibility example: client → service
Service obj = new Service(); obj.memberOne = 10; // ✓ public obj.memberTwo = 20; // ✗ private obj.doOne(); // ✓ public obj.doTwo(); // ✗ private
class Service {
public int memberOne;
private int memberTwo;
public void doOne() { … }
private void doTwo() { … }
}Exception: constants can (should) be public if outside methods are meant to use them directly.
UML visibility: + public − private
static, final, abstract.from most open to most closed
import java.util.Scanner;
class Carpeting {
//Attribute (default access)
int length;
int width;
float price;
//Method
public void calculatePrice() {
System.out.println("The carpet price is :RM"
+ length * width * price);
}
// Main Method
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Carpeting carpet = new Carpeting();
System.out.println("Enter the room length (ft.):");
carpet.length = in.nextInt();
System.out.println("Enter the room width (ft.) :");
carpet.width = in.nextInt();
System.out.println("Enter the carpet price per sq. ft. :");
carpet.price = in.nextFloat();
carpet.calculatePrice();
}
}import java.util.Scanner;
class Carpeting {
int length;
int width;
float price;
public void calculatePrice() {
System.out.println("The carpet price is :RM"
+ length * width * price);
}
}
public class A {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Carpeting carpet = new Carpeting();
...same input lines...
carpet.calculatePrice();
}
}import java.util.Random;
class Die {
private static final int MAX_NUMBER = 6;
private static final int MIN_NUMBER = 1;
private static final int NO_NUMBER = 0;
private int number;
private Random random;
public Dice( ) { // should be Die( )
random = new Random();
number = NO_NUMBER;
}
//Rolls the dice
public void roll( ) {
number = random.nextInt(MAX_NUMBER - MIN_NUMBER + 1) + MIN_NUMBER;
}
//Returns the number on this dice
public int getNumber( ) {
return number;
}
}static final → one shared copy (class constant) whose value can't change.nextInt(6 − 1 + 1) + 1 = nextInt(6) + 1 → 1 to 6.main) creates a Die and calls roll() / getNumber().class MusicCD {
private String artist;
private String title;
private String id;
public MusicCD(String name1, String name2) {
String ident;
artist = name1;
title = name2;
ident = artist.substring(0,2) + "-" +
title.substring(0,9);
id = ident;
}
...
}where each variable lives
artist · title · idname1 · name2identflow: name1 → artist, name2 → title, then artist + title build ident, then ident → id (saved in the object)
// You cannot do: Shape s = new Shape(); // ERROR!
abstract class Shape {
String color;
public void setColor(String color) {
this.color = color;
}
public static void main(String[] args) {
System.out.println("Look at the abstract conceptual");
}
}new.calling methods
dot notation is necessary when calling a method of another object
dot notation is optional when calling a method of the same object
main method.class Bicycle {
//definition of the class as shown before comes here
public static void main(String[] args) {
Bicycle myBike;
myBike = new Bicycle( );
myBike.setOwnerName("Jon Java");
System.out.println(myBike.getOwnerName() + "owns a bicycle");
}
}this Keyword & Overloadingthis is usedthisthis in any method or constructor to refer to the current object, the one that called the method or invoked the constructor.this.variable → refers to the current class instance variablethis() → invokes the current class constructorpublic class Circle {
double radius; // member variable
public Circle(double radius) { // argument
this.radius = radius;
System.out.println(radius);
}
public static void main(String [] args){
Circle circle = new Circle(789);
}
}public Circle(double radius) {
this.radius = 500;
System.out.println(radius);
System.out.println(this.radius);
}
...
Circle circle = new Circle(789);which "radius" is which?
radiusresolves to the method's argument (789.0)this.radiusrefers to this instance's member variable (500.0)Rad_radius = radius;), but radius is more meaningful, so Java gives us this to resolve the conflict.class Student10{
int id;
String name;
Student10(int id, String name){
id = id; //supposed to be this.id
name = name; //supposed to be this.name
}
void display(){System.out.println(id+" "+name);}
public static void main(String args[]){
Student10 s1 = new Student10(111,"Karan");
Student10 s2 = new Student10(321,"Aryan");
s1.display();
s2.display();
}
}Student10(int id, String name){
this.id = id;
this.name = name;
}this, id = id assigns the parameter to itself. The fields keep their defaults: 0 for int and null for String.class Student12{
int id;
String name;
Student12(int i, String n){
id = i;
name = n;
}
void display(){System.out.println(id+" "+name);}
...
Student12 e1 = new Student12(111,"karan");
Student12 e2 = new Student12(222,"Aryan");
}i, n) are different from the field names (id, name), so this isn't needed.public class TestMethodOverloading {
public int average(int n1, int n2) { // A
return (n1 + n2) / 2;
}
public double average(double n1, double n2) { // B
return (n1 + n2) / 2;
}
public int average(int n1, int n2, int n3) { // C
return (n1 + n2 + n3) / 3;
}
public static void main(String[] args) {
TestMethodOverloading tester = new TestMethodOverloading();
System.out.println(tester.average(1, 2)); // Use A
System.out.println(tester.average(1.0, 2.0)); // Use B
System.out.println(tester.average(1, 2, 3)); // Use C
System.out.println(tester.average(1.0, 2)); // Use B
// System.out.println(tester.average(1, 2, 3, 4)); // Compilation Error
}
}which version gets called?
| Call | Version | Result | Why |
|---|---|---|---|
average(1, 2) | A (int, int) | 1 | 3 / 2 → integer division |
average(1.0, 2.0) | B (double, double) | 1.5 | exact type match |
average(1, 2, 3) | C (int, int, int) | 2 | 3 arguments |
average(1.0, 2) | B | 1.5 | int 2 implicitly cast to 2.0 |
average(1, 2, 3, 4) | none | compile error | no matching method |
package Overload; as the first line puts the class into the package Overload. That's how classes are organised into a package.package Overload;
public class StudentData {
private int stuID;
private String stuName;
private int stuAge;
StudentData() { // default constructor
stuID = 100;
stuName = "New Student";
stuAge = 18;
}
StudentData(int num1, String str, int num2) { // parameterized
stuID = num1;
stuName = str;
stuAge = num2;
}
//Getter and setter methods
public int getStuID() { return stuID; }
public void setStuID(int stuID) { this.stuID = stuID; }
public String getStuName() { return stuName; }
public void setStuName(String stuName) { this.stuName = stuName; }
public int getStuAge() { return stuAge; }
public void setStuAge(int stuAge) { this.stuAge = stuAge; }
}
class TestOverloading {
public static void main(String args[]) {
StudentData myobj = new StudentData(); // default
...print name, age, ID...
StudentData myobj2 = new StudentData(555, "Chaitanya", 25); // parameterized
...print name, age, ID...
}
}two objects, two constructors
via StudentData()
via StudentData(int, String, int)
public Circle() { // 1st Constructor
radius = 1.0;
color = "red";
}
public Circle(double r) { // 2nd Constructor
radius = r;
color = "red";
}
public Circle(double r, String c) { // 3rd Constructor
radius = r;
color = c;
}this.stuID = stuID because the parameter has the same name as the field, which is exactly the case from 4.1.you've got this · good luck on the quiz