Prerequisites for Object Oriented Programming with Java
The course starts from how a computer works and quickly moves on to writing, compiling and running Java programs. The 26 topics on this page collect the background it builds on, in six groups: computer basics, number systems, algorithms and flowcharts, core programming concepts, the tools for writing Java, and two habits of thought behind objects.
Each card gives a short explanation, a small example, links to the slides where the topic is used, and a self-check question; click a question to reveal its answer.
Computer basics
What happens inside the machine when a program is stored, loaded and run.
Hardware: processor, memory and storage
A program is kept on disk as a file; to run, it is loaded into main memory (RAM), and the processor executes its instructions one by one, reading and writing data in memory. RAM is fast but loses its contents when power is lost, while the disk keeps files.
Why it mattersVariables, objects and references all live in memory while a Java program runs; only what is written to a file survives after it ends.
Self-check
A program sets int puan = 90; and then the computer is switched off. Is the value 90 still there the next day?
No. The variable exists only in RAM while the program runs. To keep the value it must be written to a file or a database.
Runtime rt = Runtime.getRuntime();
System.out.println(rt.availableProcessors()); // e.g. 8 cores
System.out.println(rt.maxMemory() / (1024 * 1024) + " MB"); // memory the JVM may useFiles, folders and paths
A path names a file: an absolute path starts from the root (C:\Users\ali\ders\Merhaba.java), a relative path starts from the current working directory (ders\Merhaba.java). The extension tells the file's type: .java is source code, .class is compiled bytecode. Windows hides known extensions by default, so a file may silently be called Merhaba.java.txt.
Why it mattersjavac and java are run in the folder that holds the source file, and file I/O opens files by relative or absolute paths.
Self-check
The working directory is C:\ders and a program opens new File("notlar.txt"). Which file does it refer to?
C:\ders\notlar.txt. A relative path is resolved against the directory the program was started from.
C:\Users\ali\ders\Merhaba.java absolute path (Windows)
/home/ali/ders/Merhaba.java absolute path (Linux, macOS)
ders\Merhaba.java relative to C:\Users\ali
Merhaba.java source code
Merhaba.class bytecode produced by javacPrograms, compilers and interpreters
A processor executes only machine code. A compiler translates a whole program in advance; an interpreter reads and executes it step by step. Java combines both: javac compiles source code into platform-independent bytecode, and the Java Virtual Machine (JVM) interprets that bytecode and compiles frequently used parts to machine code while the program runs.
Why it mattersThe difference between a compile-time error and a run-time error, and the roles of javac and java, follow from this two-step process.
Self-check
A Merhaba.class file is produced on Windows. Can it be run on Linux?
Yes. Bytecode is not machine code for a particular processor; any operating system with a JVM can run it with java Merhaba.
Merhaba.java --javac--> Merhaba.class --java (JVM)--> program output
(source code) (bytecode)Number systems & data representation
How numbers and characters are stored as bits, and the surprises that follow.
Binary, decimal and hexadecimal
In base 2 each position is worth a power of two: 1101₂ = 8 + 4 + 0 + 1 = 13. Hexadecimal groups four bits into one digit 0–9, A–F, so 1111 1111₂ = FF₁₆ = 255. Converting by repeated division by 2, and back by summing place values, should be routine.
Why it mattersBit patterns, two's complement, colour values and character codes are all written in these bases, and Java accepts binary and hexadecimal literals.
Self-check
What are 1011₂ and 2A₁₆ in decimal?
1011₂ = 8 + 2 + 1 = 11 and 2A₁₆ = 2·16 + 10 = 42.
System.out.println(Integer.toBinaryString(13)); // 1101
System.out.println(Integer.toHexString(255)); // ff
System.out.println(0b1101 + " " + 0x1F); // 13 31
System.out.println(Integer.parseInt("101", 2)); // 5Bits, bytes and integer ranges
n bits can hold 2ⁿ different values. Java stores signed integers in two's complement, so a byte (8 bits) ranges from −128 to 127 and an int (32 bits) from about −2.1 billion to 2.1 billion. When a result does not fit, it silently wraps around instead of causing an error.
Why it mattersChoosing between int and long, and recognising overflow in factorials, sums and multiplications, depends on knowing these limits.
Self-check
How many different values fit in 8 bits, and what is the range of Java's byte type?
2⁸ = 256 values; byte uses them for −128 … 127.
byte b = (byte) 130;
System.out.println(b); // -126
int max = Integer.MAX_VALUE; // 2147483647
System.out.println(max + 1); // -2147483648 (overflow)
System.out.println((long) max + 1); // 2147483648Fractions are approximate
A double stores a binary fraction, so most decimal fractions such as 0.1 are only approximated, and small errors appear in sums. Two doubles should therefore be compared with a tolerance, not with ==. Dividing two integers gives an integer: 7 / 2 is 3, while 7 / 2.0 is 3.5.
Why it mattersAverages, unit conversions and money calculations go wrong silently when these two effects are not taken into account.
Self-check
Why are amounts of money often stored as a whole number of kuruş or cents?
Integers are exact, while values such as 0.10 cannot be represented exactly as double; adding many such values accumulates rounding errors.
System.out.println(0.1 + 0.2); // 0.30000000000000004
System.out.println(0.1 + 0.2 == 0.3); // false
System.out.println(Math.abs(0.1 + 0.2 - 0.3) < 1e-9); // true
System.out.println(7 / 2 + " " + 7 / 2.0); // 3 3.5Characters: ASCII and Unicode
Every character is stored as a number: in ASCII 'A' is 65, 'a' is 97 and '0' is 48. Unicode extends this to all writing systems, so Turkish letters have codes too (ş is 351). A Java char holds a 16-bit Unicode unit and can be used in arithmetic; files usually store text in the UTF-8 encoding.
Why it mattersCharacter arithmetic such as converting '7' to 7, comparing strings, and reading Turkish text from files correctly all rely on character codes.
Self-check
'a' has the code 97. What does System.out.println('a' + 1); print?
98. char + int is computed as int; (char) ('a' + 1) would print b.
char c = 'A';
System.out.println((int) c); // 65
System.out.println((char) (c + 2)); // C
System.out.println('7' - '0'); // 7
System.out.println((int) 'ş'); // 351Algorithms & flowcharts
Planning a solution before writing code, and following code by hand.
Algorithms: input, process, output
An algorithm is a finite sequence of unambiguous steps that turns given input into the desired output and always stops. Before coding, the problem is stated clearly: what is given, what must be produced, and which special cases exist (zero, negative numbers, an empty list).
Why it mattersEvery exercise and example program in the course starts from an algorithm; most mistakes come from an unclear problem statement, not from Java syntax.
Self-check
“Keep adding 1 to x until x becomes negative.” Is this an algorithm when x starts at 5?
Not in the strict sense: on paper it never stops, because x only grows. (In Java the int would eventually overflow, which is a bug, not a plan.) An algorithm must terminate.
INPUT a, b
IF a > b THEN
max ← a
ELSE
max ← b
OUTPUT maxFrom pseudocode to code
Pseudocode states the steps of an algorithm in plain, structured language without worrying about syntax. Each line then maps to Java: INPUT to reading with Scanner, ← to assignment, REPEAT to a loop, OUTPUT to System.out.println.
Why it mattersWriting the steps first separates thinking about the solution from fighting compiler errors.
Self-check
In the example, what is printed for n = 4?
10, because 1 + 2 + 3 + 4 = 10.
sum ← 0 int sum = 0;
FOR i FROM 1 TO n for (int i = 1; i <= n; i++) {
sum ← sum + i sum = sum + i;
}
OUTPUT sum System.out.println(sum);Flowcharts and the three control structures
A flowchart draws an algorithm with standard shapes: an oval for start and end, a parallelogram for input and output, a rectangle for a computation and a diamond for a decision. Every algorithm can be built from three structures: sequence, selection (if) and iteration (loop).
Why it mattersDrawing the flow of a loop or of nested decisions makes it easier to see where a condition is checked and when the program leaves the loop.
Self-check
Which flowchart shape holds a condition such as n > 0, and how many exits does it have?
A diamond (decision); it has two exits, one for true (yes) and one for false (no).
( start / end ) oval program begins / ends
/ input, output / parallelogram Scanner, System.out.println
[ computation ] rectangle sum = sum + i;
< condition? > diamond if (n > 0), while (i <= n)Tracing code by hand
Tracing means executing a program on paper: a table records the value of every variable after each step. It is the most reliable way to predict a loop's output, find an off-by-one error, or understand someone else's code.
Why it mattersMany slides and exam questions ask for the output of a short piece of code; a trace table answers them without a computer.
Self-check
int x = 5; while (x > 1) x = x / 2; How many times does the loop body run, and what is x at the end?
Twice: x goes 5 → 2 → 1, then x > 1 is false. Finally x is 1 (integer division).
int s = 0;
for (int i = 1; i <= 4; i++) s += i;
// i : 1 2 3 4
// s : 1 3 6 10 -> loop ends when i becomes 5Programming concepts
The basic building blocks that every program is made of, whatever the language.
Variables, types and assignment
A variable is a named place in memory with a type that fixes which values it can hold. Java checks types at compile time: an int cannot hold "5", and a variable must be given a value before it is read. The = sign means assignment (copy the right side into the variable), not mathematical equality.
Why it mattersEvery program stores its data in variables; primitive and reference types later behave differently when they are assigned or passed to methods.
Self-check
int a = 3; int b = a; a = 10; What is b?
3. The assignment b = a copied the value at that moment; changing a afterwards does not affect b.
int age = 20;
double gpa = 3.25;
boolean passed = gpa >= 2.0;
String name = "Ayşe";
age = age + 1;
System.out.println(name + " " + age + " " + passed); // Ayşe 21 trueExpressions and operators
Arithmetic follows precedence rules: * / % before + −, and operators of equal precedence from left to right. The remainder operator % and integer division / together split a number into digits. When one operand of + is a String, + joins text instead of adding.
Why it mattersDigit sums, even/odd tests, divisibility and formatted output all depend on these operators.
Self-check
For n = 4729, what are n % 10 and n / 10?
9 (the last digit) and 472 (the number without its last digit).
System.out.println(17 / 5); // 3
System.out.println(17 % 5); // 2
System.out.println(2 + 3 * 4); // 14
System.out.println("1" + 2 + 3); // 123
System.out.println(1 + 2 + "3"); // 33Boolean logic
Conditions combine with && (and), || (or) and ! (not). Java evaluates them left to right and stops as soon as the result is known (short-circuit), so a later part can safely rely on an earlier check. De Morgan's laws turn negations around: !(a && b) is the same as !a || !b.
Why it mattersRange checks, input validation and loop conditions are boolean expressions; a wrong && or || is one of the most common logic errors.
Self-check
Rewrite !(x >= 1 && x <= 10) without the !.
x < 1 || x > 10, by De Morgan's law.
int x = 7;
boolean inRange = x >= 1 && x <= 10; // true
boolean outside = !(x >= 1 && x <= 10); // false: same as x < 1 || x > 10
int d = 0;
if (d != 0 && 10 / d > 1) // right side skipped: no division by zero
System.out.println("big");
System.out.println(inRange + " " + outside); // true falseDecisions: if, else if, switch
if runs a block only when its condition is true, else gives the alternative, and an else-if chain tests conditions in order, running only the first branch whose condition holds. switch selects a case by the value of a single expression.
Why it mattersGrading, menus, input checks and almost every algorithm in the course make decisions.
Self-check
int x = 5; if (x > 3) print "A"; else if (x > 1) print "B"; What is printed?
Only A. The first true condition wins and the rest of the chain is skipped, even though x > 1 is also true.
int score = 72;
if (score >= 85) System.out.println("A");
else if (score >= 70) System.out.println("B"); // B
else System.out.println("C");Loops: for, while, do-while
A loop repeats a block while its condition is true. for suits a known number of repetitions, while a condition checked before each pass, and do-while a body that must run at least once. Every loop needs a variable that changes so that the condition eventually becomes false.
Why it mattersSums, searches, patterns, input loops and array processing are all loops; infinite and off-by-one loops are frequent errors.
Self-check
How many times does for (int i = 10; i > 0; i -= 3) run?
Four times, for i = 10, 7, 4 and 1; then i becomes −2.
for (int i = 0; i < 3; i++) System.out.print(i + " "); // 0 1 2
System.out.println();
int n = 1234, digits = 0;
while (n > 0) {
n /= 10;
digits++;
}
System.out.println(digits); // 4Functions: parameters and return values
A function (in Java, a method) packages a computation under a name: it receives values through parameters and may return one result with return; a void method returns nothing. Java passes arguments by value, so a method cannot change the caller's int variable.
Why it mattersPrograms are divided into methods from the start, and classes are collections of methods and data.
Self-check
static void inc(int x) { x++; } After int a = 5; inc(a); what is a?
Still 5. The method received a copy of the value; it changed only its own parameter x.
static int square(int x) { return x * x; }
static void greet(String name) { System.out.println("Hi " + name); }
// in main:
int r = square(5) + square(2); // 29
greet("Ali"); // Hi AliArrays and strings: first contact
An array holds a fixed number of values of one type, numbered from index 0 to length − 1. A String is a sequence of characters whose positions are also numbered from 0. Reading outside these limits stops the program with an exception.
Why it mattersLists of grades, matrices, text processing and the collection classes all build on indexed access.
Self-check
int[] a = {4, 8, 15}; What happens when a[3] is read?
An ArrayIndexOutOfBoundsException is thrown; the valid indices are 0, 1 and 2.
int[] a = {4, 8, 15};
System.out.println(a.length + " " + a[0] + " " + a[a.length - 1]); // 3 4 15
String s = "Java";
System.out.println(s.length() + " " + s.charAt(1)); // 4 aTools & setup
Installing Java, compiling and running programs, and reading what the tools report.
Command line basics
The command line (Command Prompt or PowerShell on Windows, Terminal on macOS and Linux) runs programs by typing their names. The prompt shows the current working directory; cd changes it, dir (ls on macOS/Linux) lists its files, and mkdir creates a folder. The Tab key completes file names and the up arrow repeats earlier commands.
Why it mattersjavac and java are command-line programs; running them by hand shows what an IDE does behind its Run button.
Self-check
The prompt shows C:\Users\ali\ders>. What is the working directory after cd .. ?
C:\Users\ali, the parent folder.
C:\Users\ali> mkdir ders create a folder
C:\Users\ali> cd ders enter it
C:\Users\ali\ders> dir list its files (ls on macOS/Linux)
C:\Users\ali\ders> cd .. go up one level
C:\Users\ali>Installing the JDK
The Java Development Kit (JDK) contains the compiler javac, the java launcher with the JVM, and the standard library. A long-term-support release such as JDK 17 or 21 (for example from Adoptium or Oracle) is a good choice. The installer, or the user, must add the JDK's bin folder to the PATH so that the commands work in any directory; java -version and javac -version confirm the installation.
Why it mattersWithout a working JDK neither the command-line examples nor an IDE can compile Java code.
Self-check
The command line answers 'javac' is not recognized as an internal or external command. What is the likely cause?
The JDK's bin folder is not on the PATH, or only a runtime without the compiler is installed.
> java -version
openjdk version "21.0.3" 2024-04-16 LTS
OpenJDK Runtime Environment Temurin-21.0.3+9 (build 21.0.3+9-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.3+9 (build 21.0.3+9-LTS, mixed mode, sharing)
> javac -version
javac 21.0.3javac and java: compile and run
javac Merhaba.java compiles the source file and, if there are no errors, writes Merhaba.class; java Merhaba then starts the JVM and runs the main method of that class (the name is given without .class). A public class must be saved in a file with exactly the same name, including upper and lower case.
Why it mattersEvery program in the course has this shape: a class with a main method, compiled and then run.
Self-check
A file named Test.java contains public class Merhaba. What does javac Test.java report?
A compile error: class Merhaba is public, should be declared in a file named Merhaba.java.
public class Merhaba {
public static void main(String[] args) {
System.out.println("Merhaba, Java!");
}
}
> javac Merhaba.java (creates Merhaba.class)
> java Merhaba
Merhaba, Java!Working in an IDE
An integrated development environment combines an editor, the compiler and a debugger: it underlines errors while typing, completes names, and its Run button compiles and runs the program. Common choices are IntelliJ IDEA, Eclipse and Visual Studio Code with Java extensions. The debugger stops at a breakpoint and executes the program line by line while showing the variables.
Why it mattersLarger programs with several classes are written in an IDE, and the debugger replaces hand tracing for longer code.
Self-check
The debugger is stopped on the line int r = square(5);. What is the difference between Step Over and Step Into?
Step Over runs the whole call and stops on the next line of the current method; Step Into enters square and stops on its first line.
IntelliJ IDEA psvm + Tab -> public static void main(String[] args)
IntelliJ IDEA sout + Tab -> System.out.println();
Eclipse main + Ctrl+Space, sysout + Ctrl+Space
all IDEs click the margin next to a line to set a breakpointReading error messages
A compile-time error is reported by javac with the file name, the line number and a caret (^) under the problem; no .class file is produced. A run-time error is an exception: the program compiles but stops while running, printing the exception type, a message and the stack trace of method calls. The first message and its line number are usually the place to start.
Why it mattersFixing errors quickly depends on reading these messages instead of guessing.
Self-check
Is int x = "5"; a compile-time error or a run-time error?
A compile-time error (incompatible types: String cannot be converted to int); javac rejects it before the program can run.
Merhaba.java:3: error: ';' expected
System.out.println("Merhaba")
^
1 error
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Bolme.main(Bolme.java:4)Reading API documentation
The Java standard library is documented in Javadoc pages (docs.oracle.com) organised by package and class. A method's signature tells what it needs and what it gives back: in public static int parseInt(String s), the parameter is a String, the result is an int, and static means it is called on the class, as Integer.parseInt("42").
Why it mattersClasses such as String, Math, Scanner, ArrayList and HashMap are used through their documented methods.
Self-check
Math.max has versions for int and for double. What does Math.max(3, 7.5) return?
7.5 as a double: since one argument is a double, the double version is chosen and 3 is widened to 3.0.
public static int parseInt(String s) // in class Integer
public int length() // in class String
public static double sqrt(double a) // in class Math
int n = Integer.parseInt("42") + 1; // 43
int k = "Java".length(); // 4
double r = Math.sqrt(16); // 4.0Thinking ahead to objects
Two habits of thought that object-oriented programming builds on.
Classification: is-a and has-a
Everyday things fall into categories (every dog is an animal) and are made of parts (a car has an engine). Object-oriented programming models the first relationship with inheritance (is-a) and the second with fields that refer to other objects (has-a). Telling the two apart in a sentence is the first step of class design.
Why it mattersChoosing between extends and a field, and building class hierarchies, starts from this distinction.
Self-check
A student has a student number; a student is a person. Which relationship is is-a and which is has-a?
Student is-a Person (inheritance); Student has-a student number (a field).
class Animal { }
class Dog extends Animal { } // a Dog is an Animal
class Engine { }
class Car {
Engine engine = new Engine(); // a Car has an Engine
}Abstraction and decomposition
Decomposition splits a large problem into smaller parts that can be solved separately; abstraction keeps only what matters about a part and hides how it works inside. Using Math.sqrt without knowing its algorithm is abstraction; writing a program as several small methods is decomposition.
Why it mattersMethods, classes, interfaces and encapsulation are tools for these two ideas.
Self-check
A program reads grades, computes their average and prints a report. Into which parts could it be split?
For example into three methods: one that reads the grades, one that computes the average, and one that prints the report; each can be written and tested on its own.
static int[] readGrades() { ... }
static double average(int[] g) { ... }
static void printReport(double avg) { ... }
// main only combines the parts:
printReport(average(readGrades()));No topic matches the current search and filter.
The outputs in the Java examples were checked by compiling with javac --release 8 and running the programs; outputs marked “e.g.” depend on the computer.