[Go to site: main page, start]

0% found this document useful (0 votes)
3 views41 pages

Java Complete Notes

This document provides comprehensive notes on Java programming, covering core concepts such as programming languages, Java features, code execution, variables, data types, operators, decision-making statements, and looping statements. It explains the structure and syntax of Java, including examples of basic programming constructs and their functionalities. The notes are designed for beginners to intermediate learners, facilitating a deeper understanding of Java programming principles.

Uploaded by

kirtiip10
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views41 pages

Java Complete Notes

This document provides comprehensive notes on Java programming, covering core concepts such as programming languages, Java features, code execution, variables, data types, operators, decision-making statements, and looping statements. It explains the structure and syntax of Java, including examples of basic programming constructs and their functionalities. The notes are designed for beginners to intermediate learners, facilitating a deeper understanding of Java programming principles.

Uploaded by

kirtiip10
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Complete Java Programming Notes

Core Concepts · OOP · String Handling · Type Casting


Detailed Study Notes — Beginner to Intermediate
1. Introduction to Programming Language
What is a Programming Language?
A programming language is a formal set of instructions used to produce output and control the
behaviour of a machine. It acts as a bridge between human logic and machine execution.

Types of Programming Languages


• Machine Language (Low Level) — Binary code (0s and 1s), directly understood by CPU.
Extremely fast but very difficult to write.
• Assembly Language — Uses mnemonics like MOV, ADD. One step above machine language.
Still hardware-dependent.
• High-Level Language — Human-readable syntax (Java, C++, Python). Compiler/Interpreter
converts to machine code.

What is Java?
Java is a high-level, class-based, object-oriented programming language developed by James Gosling
at Sun Microsystems in 1995. It follows the principle: Write Once, Run Anywhere (WORA).

Java Platform Components


Component Full Form Role
JDK Java Development Kit Full package for developers —
includes JRE + compiler (javac)
+ tools like javadoc, jar
JRE Java Runtime Environment Used to run Java programs —
includes JVM + standard class
libraries
JVM Java Virtual Machine Abstract machine that executes
Java bytecode. Platform-specific
but bytecode is platform-
independent

How Java Code Executes


Source Code (.java)
↓ javac (compiler)
Bytecode (.class)
↓ JVM (interpreter/JIT compiler)
Machine Code (executed on OS)
📌 Note: The .class file (bytecode) is NOT machine code. It is an intermediate format understood by
the JVM, not the CPU directly.

Features of Java
• Simple — Easy to learn; syntax similar to C/C++ but without complex features like pointers
• Object-Oriented — Everything is modelled as objects and classes
• Platform Independent — Bytecode runs on any OS with a JVM
• Robust — Strong memory management, exception handling, type checking
• Secure — No explicit pointer access; security manager controls resource access
• Multithreaded — Built-in support for concurrent execution
• Portable — Same bytecode runs across platforms
• High Performance — JIT (Just In Time) compiler optimises bytecode at runtime

First Java Program Explained


public class HelloWorld {
public static void main(String[] args) {
[Link]("Hello, World!");
}
}

Keyword/Part Meaning
public Access modifier — visible to all
class Declares a class named HelloWorld
static Method belongs to class, not an object; called
without creating object
void Method returns no value
main Entry point — JVM starts execution here
String[] args Array to receive command-line arguments
[Link] Prints text to console and moves to next line
2. Java Tokens
Tokens are the smallest individual units in a Java program — the building blocks the compiler reads.

Types of Java Tokens


Token Type Description Example
Keywords Reserved words with special int, class, if, for, return, static
meaning
Identifiers Names for variables, methods, myVar, calculateSum, Student
classes
Literals Fixed constant values in code 42, 3.14, 'A', "Hello", true
Operators Symbols that perform +, -, *, /, ==, &&, ++
operations
Separators Characters that structure code {}()[];,.
Comments Non-executable documentation // single line, /* multi-line */
text

Keywords (50 Reserved Words)


abstract assert boolean break byte case
catch char class const continue default
do double else enum extends final
finally float for goto if implements
import instanceof int interface long native
new package private protected public return
short static strictfp super switch synchronized
this throw throws transient try void
volatile while
📌 Note: const and goto are reserved but not used in Java. true, false, and null are literals, not
keywords.

Identifier Rules
• Can contain letters (a-z, A-Z), digits (0-9), underscore (_), dollar sign ($)
• Must NOT start with a digit
• Cannot be a keyword
• Case-sensitive (age, Age, AGE are three different identifiers)
• No length limit (but keep it meaningful)

Identifier Naming Conventions


Category Convention Example
Variables / Methods camelCase — start lowercase studentName, calculateSum()
Classes / Interfaces PascalCase — start uppercase StudentRecord, Runnable
Constants UPPER_SNAKE_CASE MAX_SIZE, PI_VALUE
Category Convention Example
Packages all lowercase, dot-separated [Link]

Literals in Detail
Literal Type Example Notes
Integer 42, 0xFF (hex), 0b1010 (binary), Default type is int; add L for
0755 (octal) long: 100L
Floating Point 3.14, 2.5f, 1.0e10 Default is double; add f for float
Character 'A', '\n', '\t', '\\', '\'' Single quotes; uses Unicode
String "Hello", "Line1\nLine2" Double quotes; objects of String
class
Boolean true, false Only these two values;
lowercase
Null null Represents no object reference
3. Variables and Data Types
What is a Variable?
A variable is a named memory location that stores a value. The value can change during program
execution. Every variable has a type, a name, and a value.

// Syntax: dataType variableName = value;


int age = 21;
double salary = 45000.50;
String name = "Ravi";
boolean isActive = true;

Types of Variables
Type Where Declared Scope Default Value
Local Variable Inside a method or Only inside that No default — must
block method/block initialise
Instance Variable Inside class, outside Throughout the object's int→0, double→0.0,
method life boolean→false,
Object→null
Static Variable Inside class with static Shared across all Same defaults as
keyword objects (class-level) instance variables

public class VariableDemo {


int instanceVar = 10; // instance variable
static int staticVar = 100; // static variable

void display() {
int localVar = 5; // local variable
[Link](localVar + instanceVar + staticVar);
}
}

Data Types in Java


Java is a strongly typed language — every variable must have a declared type. There are two
categories:

Primitive Data Types (8 Types)


Type Size Default Range Example
byte 1 byte 0 -128 to 127 byte b = 100;
short 2 bytes 0 -32,768 to 32,767 short s = 30000;
int 4 bytes 0 -2^31 to 2^31-1 int x = 100000;
(~2 billion)
long 8 bytes 0L -2^63 to 2^63-1 long l =
9876543210L;
Type Size Default Range Example
float 4 bytes 0.0f ~7 decimal digits float f = 3.14f;
precision
double 8 bytes 0.0d ~15 decimal digits double d =
precision 3.14159265;
char 2 bytes '\u0000' 0 to 65,535 char c = 'A';
(Unicode)
boolean 1 bit (JVM dep.) false true or false only boolean flag =
true;

Non-Primitive (Reference) Types


• String — Sequence of characters. Immutable object.
• Array — Collection of same-type elements stored in contiguous memory.
• Class — User-defined blueprint for objects.
• Interface — Contract that classes must follow.

Type Casting
Converting one data type to another.

Type Description Direction Example


Widening (Implicit) Smaller type → Larger byte→short→int→long int x=10; double d=x;
type. Done →float→double
automatically, no data
loss.
Narrowing (Explicit) Larger type → Smaller double→float→long→i double d=9.7; int
type. Must be done nt→short→byte x=(int)d; // x=9
manually. Possible
data loss.

// Widening (automatic)
int i = 100;
long l = i; // int → long (no cast needed)
double d = l; // long → double

// Narrowing (explicit)
double pi = 3.99;
int truncated = (int) pi; // truncated = 3 (decimal part lost)

// char ↔ int
char ch = 'A';
int ascii = ch; // ascii = 65
char back = (char) 66; // back = 'B'
4. Operators
An operator is a symbol that tells the compiler to perform a specific mathematical, relational, or logical
operation.

Arithmetic Operators
Operator Name Example Result
+ Addition 10 + 3 13
- Subtraction 10 - 3 7
* Multiplication 10 * 3 30
/ Division 10 / 3 3 (integer division)
% Modulus (Remainder) 10 % 3 1

Relational (Comparison) Operators


Operator Meaning Example Result
== Equal to 5 == 5 true
!= Not equal to 5 != 3 true
> Greater than 5>3 true
< Less than 5<3 false
>= Greater than or equal 5 >= 5 true
<= Less than or equal 3 <= 5 true

Logical Operators
Operator Name Usage Returns true when
&& Logical AND a && b Both a AND b are true
|| Logical OR a || b At least one of a OR b
is true
! Logical NOT !a a is false (inverts
result)
✅ Key Point: && and || use short-circuit evaluation. For &&, if the first operand is false, the second
is NOT evaluated. For ||, if first is true, second is NOT evaluated.

Assignment Operators
Operator Equivalent To Example After execution
= — x = 10 x = 10
+= x = x + val x += 5 x = 15
Operator Equivalent To Example After execution
-= x = x - val x -= 3 x = 12
*= x = x * val x *= 2 x = 24
/= x = x / val x /= 4 x=6
%= x = x % val x %= 4 x=2

Increment & Decrement Operators


Operator Name Example Explanation
++x Pre-increment int a=5; int b=++a; a becomes 6 first, then
b=6
x++ Post-increment int a=5; int b=a++; b=5 first, then a
becomes 6
--x Pre-decrement int a=5; int b=--a; a becomes 4 first, then
b=4
x-- Post-decrement int a=5; int b=a--; b=5 first, then a
becomes 4

Bitwise Operators
Operator Name Example (a=5=0101, Result
b=3=0011)
& Bitwise AND a&b 0001 = 1
| Bitwise OR a|b 0111 = 7
^ Bitwise XOR a^b 0110 = 6
~ Bitwise NOT ~a ...11111010 = -6
<< Left Shift a << 1 1010 = 10 (multiply by
2)
>> Right Shift a >> 1 0010 = 2 (divide by 2)
>>> Unsigned Right Shift a >>> 1 0010 = 2 (no sign
extension)

Ternary Operator
The only operator with three operands. It is a shorthand for if-else.
// Syntax: condition ? valueIfTrue : valueIfFalse
int a = 10, b = 20;
int max = (a > b) ? a : b; // max = 20

String result = (age >= 18) ? "Adult" : "Minor";


instanceof Operator
Checks whether an object is an instance of a specific class or interface.
String s = "Hello";
[Link](s instanceof String); // true

Object obj = new Integer(5);


[Link](obj instanceof Integer); // true
[Link](obj instanceof String); // false

Operator Precedence (Highest to Lowest)


Priority Operators Type
1 (Highest) () [] . Parentheses, array access,
member access
2 ++ -- ~ ! Unary operators
3 */% Multiplicative
4 +- Additive
5 << >> >>> Shift
6 < <= > >= instanceof Relational
7 == != Equality
8 & Bitwise AND
9 ^ Bitwise XOR
10 | Bitwise OR
11 && Logical AND
12 || Logical OR
13 ?: Ternary
14 (Lowest) = += -= *= /= %= Assignment
5. Decision Making Statements
Decision-making statements control the flow of program execution based on conditions. Java provides
if, if-else, if-else-if ladder, nested if, and switch.

1. Simple if Statement
// Executes block only if condition is true
int marks = 75;
if (marks >= 40) {
[Link]("Pass");
}

2. if-else Statement
int age = 16;
if (age >= 18) {
[Link]("Can vote");
} else {
[Link]("Cannot vote");
}

3. if-else-if Ladder
Used to test multiple conditions in sequence. Once a condition is true, the rest are skipped.
int marks = 82;
if (marks >= 90) {
[Link]("Grade A");
} else if (marks >= 75) {
[Link]("Grade B");
} else if (marks >= 60) {
[Link]("Grade C");
} else if (marks >= 40) {
[Link]("Grade D");
} else {
[Link]("Fail");
}

4. Nested if
int age = 25;
boolean hasLicense = true;
if (age >= 18) {
if (hasLicense) {
[Link]("Can drive");
} else {
[Link]("Need a license");
}
} else {
[Link]("Too young to drive");
}
5. switch Statement
Efficiently handles multiple fixed values of a single variable. Works with int, char, String, enum (not
float/double).
int day = 3;
switch (day) {
case 1:
[Link]("Monday");
break;
case 2:
[Link]("Tuesday");
break;
case 3:
[Link]("Wednesday");
break;
default:
[Link]("Other day");
}
📌 Note: Without break, execution 'falls through' to the next case. This can be intentional (to handle
multiple cases with same logic) or a bug.

// Fall-through example (intentional)


int month = 4;
switch (month) {
case 4: case 6: case 9: case 11:
[Link]("30 days");
break;
case 2:
[Link]("28 or 29 days");
break;
default:
[Link]("31 days");
}
6. Looping Statements
Loops repeat a block of code multiple times. Java provides for, while, do-while, and enhanced for (for-
each).

1. for Loop
Best when the number of iterations is known in advance.
// Syntax: for (initialization; condition; update)
for (int i = 1; i <= 5; i++) {
[Link]("Count: " + i);
}

// Sum of first 100 natural numbers


int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
[Link]("Sum = " + sum); // 5050

2. while Loop
Best when the number of iterations is NOT known, and the condition is checked BEFORE each
iteration.
// Count down from 5
int n = 5;
while (n > 0) {
[Link](n);
n--;
}

// Read until -1 entered (sentinel loop)


Scanner sc = new Scanner([Link]);
int num = [Link]();
while (num != -1) {
[Link]("Got: " + num);
num = [Link]();
}

3. do-while Loop
The body executes AT LEAST ONCE because condition is checked AFTER the first iteration.
int i = 1;
do {
[Link]("Iteration: " + i);
i++;
} while (i <= 5);

// Practical use: menu-driven program


int choice;
do {
[Link]("1. Add 2. Sub 3. Exit");
choice = [Link]();
// process choice...
} while (choice != 3);
✅ Key Point: Use do-while when you need the loop to run at least once regardless of the condition
— like showing a menu before reading user input.

4. Enhanced for Loop (for-each)


Simplifies iteration over arrays and collections. Cannot modify elements; read-only.
int[] numbers = {10, 20, 30, 40, 50};
for (int num : numbers) {
[Link](num);
}

String[] fruits = {"Apple", "Banana", "Cherry"};


for (String fruit : fruits) {
[Link](fruit);
}

Nested Loops
A loop inside another loop. The inner loop completes fully for every single iteration of the outer loop.
// Multiplication table
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
[Link](i * j + "\t");
}
[Link]();
}
// Output:
// 1 2 3
// 2 4 6
// 3 6 9

Comparison of Loops
Loop Condition Check Min Executions Best Used When
for Before each iteration 0 Number of iterations is
known
while Before each iteration 0 Iteration count is
unknown; pre-check
needed
do-while After each iteration 1 (always) Body must run at least
once
for-each Before each element 0 Iterating arrays or
collections
7. Jumping Statements
1. break Statement
Immediately exits the nearest enclosing loop or switch block. Execution continues at the statement after
the loop.
// Stop searching when found
int[] arr = {3, 7, 2, 9, 5};
int target = 9;
for (int i = 0; i < [Link]; i++) {
if (arr[i] == target) {
[Link]("Found at index: " + i);
break; // exit loop immediately
}
}

// Labeled break (break outer loop from inner)


outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) break outer;
[Link](i + "," + j);
}
}

2. continue Statement
Skips the rest of the current loop iteration and jumps to the next iteration. Does NOT exit the loop.
// Print only odd numbers
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) continue; // skip even numbers
[Link](i);
}
// Output: 1 3 5 7 9

// Labeled continue
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) continue outer; // skip to next i
[Link](i + "," + j);
}
}

3. return Statement
Exits the current method and optionally returns a value to the caller.
// Return a value
int add(int a, int b) {
return a + b; // exits method and returns sum
}

// Void method — return used to exit early


void printPositive(int n) {
if (n <= 0) return; // exit early
[Link](n);
}

break vs continue vs return


Statement What It Does Where Used
break Exits the loop or switch for, while, do-while, switch
completely
continue Skips current iteration, for, while, do-while
continues loop
return Exits the method; can return a Any method
value
8. Methods
What is a Method?
A method is a named block of code that performs a specific task. It promotes code reuse, readability,
and modular design. Methods are also called functions in other languages.

Method Syntax
accessModifier returnType methodName(parameter1, parameter2, ...) {
// method body
return value; // only if returnType is not void
}

Example — Method with Parameters and Return


public int multiply(int a, int b) {
int result = a * b;
return result;
}

// Calling the method


int answer = multiply(4, 5); // answer = 20

Types of Methods
Type Returns? Has Parameters? Example
No param, no return No (void) No void greet() { ... }
With param, no return No (void) Yes void printName(String
n) { ... }
No param, with return Yes No int getMax() { return
100; }
With param and return Yes Yes int add(int a, int b)
{ return a+b; }

Method Overloading
Same method name, different parameter lists (different type, number, or order). Resolved at compile
time (static polymorphism).
class Calculator {
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
int add(int a, int b, int c) { return a + b + c; }

// Note: CANNOT overload by return type alone


// int foo() vs double foo() — NOT valid overloading
}
Recursion
A method calling itself. Every recursive method must have a base case to prevent infinite recursion.
// Factorial using recursion
int factorial(int n) {
if (n == 0 || n == 1) return 1; // base case
return n * factorial(n - 1); // recursive call
}
// factorial(5) = 5 × 4 × 3 × 2 × 1 = 120

// Fibonacci
int fib(int n) {
if (n <= 1) return n;
return fib(n-1) + fib(n-2);
}

Variable Arguments (Varargs)


A method that can accept a variable number of arguments of the same type.
int sum(int... numbers) {
int total = 0;
for (int n : numbers) total += n;
return total;
}

sum(1, 2); // 3
sum(1, 2, 3, 4, 5); // 15

Pass by Value in Java


Java always passes arguments by value, not by reference. For primitives, a copy of the value is
passed. For objects, a copy of the reference (memory address) is passed.
void change(int x) { x = 99; } // x is a copy

int a = 10;
change(a);
[Link](a); // Still 10! Original unchanged

// For objects — the object's state CAN be changed


// but reassigning the reference inside method won't affect caller
9. Static and Non-Static Members
Static Members
Static members belong to the CLASS, not to any individual object. They are shared across all
instances. Declared with the static keyword.

Static Variables
class Counter {
static int count = 0; // shared by all objects
String name;

Counter(String n) {
name = n;
count++;
}
}

Counter c1 = new Counter("A");


Counter c2 = new Counter("B");
Counter c3 = new Counter("C");
[Link]([Link]); // 3 (same for all)

Static Methods
class MathUtil {
static int square(int n) { // static method
return n * n;
}
}

// Called on class name, no object needed


int result = [Link](5); // 25
✅ Key Point: A static method CANNOT access instance (non-static) variables or call non-static
methods directly — because non-static members need an object, and static methods have no this
reference.

Static Block
Executed once when the class is first loaded, before any constructor runs. Used for static initialization.
class Config {
static String dbUrl;
static {
dbUrl = "jdbc:mysql://localhost/mydb";
[Link]("Config loaded!");
}
}

Non-Static (Instance) Members


Non-static members belong to individual objects. Each object has its own copy of instance variables.
class Student {
String name; // instance variable — each object has its own
int marks;

void display() { // instance method


[Link](name + " scored " + marks);
}
}

Student s1 = new Student();


[Link] = "Ravi"; [Link] = 90;

Student s2 = new Student();


[Link] = "Priya"; [Link] = 85;

[Link](); // Ravi scored 90


[Link](); // Priya scored 85

Static vs Non-Static — Full Comparison


Aspect Static Non-Static (Instance)
Belongs to The Class Individual Object
Memory One copy for all objects Separate copy per object
Access [Link] [Link]
When created When class loads into JVM When new object is created
Can access static members? Yes Yes
Can access non-static No (no 'this' reference) Yes
members?
Use case Shared data, utility methods, Object-specific data and
constants behaviour

The this Keyword


this refers to the current object inside an instance method or constructor. Used to: (1) distinguish
between instance variable and parameter, (2) call another constructor in same class.
class Person {
String name;
int age;

Person(String name, int age) {


[Link] = name; // '[Link]' = instance var; 'name' = parameter
[Link] = age;
}

// Constructor chaining using this()


Person(String name) {
this(name, 0); // calls Person(String, int)
}
}
10. Object-Oriented Programming (OOP)
What is OOP?
Object-Oriented Programming is a programming paradigm that organises software around objects —
entities that combine data (attributes) and behaviour (methods). Java is a pure OOP language (except
for primitive types).

4 Pillars of OOP
Pillar Definition Java Mechanism
Encapsulation Bundling data and methods; private fields + public
hiding internal state getters/setters
Inheritance A class acquires properties of extends keyword
another class
Polymorphism Same name, different behaviour Method overloading & overriding
depending on context
Abstraction Hiding complexity; showing only abstract class, interface
what is needed

Classes and Objects


// Class is the blueprint / template
class Car {
// Attributes (fields)
String brand;
int speed;

// Constructor — called when object is created


Car(String brand, int speed) {
[Link] = brand;
[Link] = speed;
}

// Behaviour (methods)
void accelerate() {
speed += 10;
[Link](brand + " now at " + speed + " kmph");
}
}

// Object is the actual instance


Car myCar = new Car("Toyota", 60);
[Link](); // Toyota now at 70 kmph

Constructors
Type Description Example
Default Provided by Java if no Car() { }
constructor defined. Sets all
Type Description Example
fields to defaults.
No-arg User-defined constructor with no Car() { brand="Unknown"; }
parameters.
Parameterised Accepts arguments to initialise Car(String b, int s) { ... }
fields.
Copy Creates a new object as a copy Car(Car c) { [Link]=[Link];
of another object. }
11. Encapsulation
What is Encapsulation?
Encapsulation means bundling the data (fields) and the methods that operate on that data together in a
single unit (class), and restricting direct access to the data from outside the class. This is achieved by
making fields private and providing public getter and setter methods.

Why Encapsulation?
• Data hiding — internal representation is hidden from misuse
• Control — can validate data before setting values
• Flexibility — can change internal implementation without affecting external code
• Read-only or write-only fields — by providing only getter or only setter

public class BankAccount {


private double balance; // PRIVATE — cannot access directly from outside
private String owner;

public BankAccount(String owner, double initialBalance) {


[Link] = owner;
if (initialBalance < 0) throw new IllegalArgumentException("Balance
cannot be negative");
[Link] = initialBalance;
}

// Getter — read-only access


public double getBalance() { return balance; }
public String getOwner() { return owner; }

// Controlled mutation — validation inside setter


public void deposit(double amount) {
if (amount <= 0) throw new IllegalArgumentException("Amount must be
positive");
balance += amount;
}

public void withdraw(double amount) {


if (amount > balance) throw new IllegalArgumentException("Insufficient
funds");
balance -= amount;
}
}

// Usage
BankAccount acc = new BankAccount("Ravi", 5000);
[Link](1000);
// [Link] = -9999; // ERROR — private field
[Link]([Link]()); // 6000.0
Access Modifiers
Modifier Same Class Same Package Subclass (diff Other Classes
pkg)
private ✅ Yes ❌ No ❌ No ❌ No
(default / ✅ Yes ✅ Yes ❌ No ❌ No
package)
protected ✅ Yes ✅ Yes ✅ Yes ❌ No
public ✅ Yes ✅ Yes ✅ Yes ✅ Yes
📌 Note: Use private for all fields (data). Use public for methods that form the class's interface. Use
protected when subclasses need access. Avoid default unless intentional.
12. Has-A Relationship
What is Has-A Relationship?
A Has-A relationship means one class contains a reference to another class as a member variable.
This is also called Composition or Aggregation. It models 'whole-part' relationships.

Composition (Strong Has-A)


The contained object cannot exist independently. If the container is destroyed, the contained object is
also destroyed.
// A House HAS-A Room. Rooms don't exist without the House.
class Room {
String type;
Room(String type) { [Link] = type; }
}

class House {
private Room livingRoom; // Composition — House owns Room
private Room bedroom;

House() {
livingRoom = new Room("Living Room"); // created inside House
bedroom = new Room("Bedroom");
}
// When House object dies, Room objects die too
}

Aggregation (Weak Has-A)


The contained object CAN exist independently. If the container is destroyed, the contained object
continues to exist.
// A Department HAS-A Professor. Professor can exist without Department.
class Professor {
String name;
Professor(String name) { [Link] = name; }
}

class Department {
String deptName;
Professor prof; // Aggregation — Professor passed from outside

Department(String deptName, Professor prof) {


[Link] = deptName;
[Link] = prof; // Professor exists independently
}
}

Professor p = new Professor("Dr. Sharma");


Department d = new Department("CS", p);
// p still exists even if d is garbage collected
Has-A vs Is-A
Relationship Type Mechanism Example
Is-A Inheritance extends / implements Dog IS-A Animal
Has-A (Composition) Strong containment Creates object House HAS-A Room
internally
Has-A (Aggregation) Weak containment Receives object as Department HAS-A
parameter Professor
✅ Key Point: Prefer Has-A (composition) over Is-A (inheritance) when possible — it creates more
flexible, loosely-coupled code. This is the famous 'Favour composition over inheritance' principle.
13. Is-A Relationship (Inheritance)
What is Inheritance?
Inheritance allows a class (child/subclass) to acquire the properties and methods of another class
(parent/superclass). It promotes code reuse and establishes a parent-child hierarchy.
// Syntax: class ChildClass extends ParentClass
class Animal {
String name;
void eat() { [Link](name + " is eating"); }
void breathe() { [Link]("Breathing air"); }
}

class Dog extends Animal {


void bark() { [Link](name + " says: Woof!"); }
}

Dog d = new Dog();


[Link] = "Bruno";
[Link](); // Inherited from Animal
[Link]();// Inherited from Animal
[Link](); // Dog's own method

Types of Inheritance
Type Description Java Support
Single One child inherits from one ✅ Supported
parent
Multilevel A → B → C (chain of ✅ Supported
inheritance)
Hierarchical Multiple children share one ✅ Supported
parent
Multiple One child inherits from two ❌ NOT supported with classes
parents (only via interfaces)
Hybrid Combination of above types ✅ Partial (via interfaces)

Multilevel Inheritance
class Vehicle {
void start() { [Link]("Vehicle starting"); }
}

class Car extends Vehicle {


void drive() { [Link]("Car driving"); }
}

class ElectricCar extends Car { // inherits from Car AND Vehicle


void charge() { [Link]("Charging battery"); }
}

ElectricCar ec = new ElectricCar();


[Link](); // from Vehicle
[Link](); // from Car
[Link](); // own method

super Keyword
super refers to the immediate parent class. Used to: (1) call parent constructor, (2) call parent method,
(3) access parent field.
class Animal {
String name;
Animal(String name) { [Link] = name; }
void describe() { [Link]("Animal: " + name); }
}

class Cat extends Animal {


String colour;

Cat(String name, String colour) {


super(name); // MUST be first line — calls Animal constructor
[Link] = colour;
}

void describe() {
[Link](); // calls Animal's describe()
[Link]("Colour: " + colour);
}
}

Method Overriding
When a subclass provides its own implementation of a method that is already defined in the parent
class. The method signature must be identical.
class Shape {
double area() { return 0; }
}

class Circle extends Shape {


double radius;
Circle(double r) { [Link] = r; }

@Override // annotation — optional but STRONGLY recommended


double area() { return [Link] * radius * radius; }
}

class Rectangle extends Shape {


double w, h;
Rectangle(double w, double h) { this.w = w; this.h = h; }

@Override
double area() { return w * h; }
}
Overriding Rules
• Method name and parameter list must be exactly the same
• Return type must be same or a covariant (subtype) return type
• Access modifier cannot be more restrictive than the parent method
• static, final, and private methods CANNOT be overridden
• Constructors are NOT inherited and cannot be overridden

final Keyword
Usage Effect
final variable Value cannot be changed after assignment
(constant)
final method Cannot be overridden in any subclass
final class Cannot be extended (inherited from)
14. Polymorphism
What is Polymorphism?
Polymorphism means 'many forms'. In Java, it allows one interface to be used for many types. The
same method name behaves differently based on the object it is called on.

Type Also Called Resolved At Mechanism


Compile-time (Static) Method Overloading, Compile time Same method name,
Early Binding different parameters
Runtime (Dynamic) Method Overriding, Runtime Subclass overrides
Late Binding parent method; parent
reference used

Compile-time Polymorphism (Overloading)


class Printer {
void print(int n) { [Link]("Integer: " + n); }
void print(double d) { [Link]("Double: " + d); }
void print(String s) { [Link]("String: " + s); }
void print(int a, int b) { [Link]("Sum: " + (a+b)); }
}

Printer p = new Printer();


[Link](5); // Integer: 5
[Link](3.14); // Double: 3.14
[Link]("Hello"); // String: Hello
[Link](3, 7); // Sum: 10

Runtime Polymorphism (Overriding + Upcasting)


The key to runtime polymorphism is that a parent class reference can hold a child class object. When a
method is called, Java determines at RUNTIME which class's version to execute.
class Animal {
void sound() { [Link]("Some sound"); }
}
class Dog extends Animal {
void sound() { [Link]("Woof!"); }
}
class Cat extends Animal {
void sound() { [Link]("Meow!"); }
}
class Duck extends Animal {
void sound() { [Link]("Quack!"); }
}

// Parent reference holds child object (Upcasting)


Animal a1 = new Dog();
Animal a2 = new Cat();
Animal a3 = new Duck();

[Link](); // Woof! (decided at runtime)


[Link](); // Meow!
[Link](); // Quack!

// Powerful with arrays/loops


Animal[] animals = { new Dog(), new Cat(), new Duck() };
for (Animal a : animals) {
[Link](); // each calls its own version
}
✅ Key Point: The reference type (Animal) determines which methods CAN be called. The actual
object type (Dog, Cat) determines which VERSION of the method runs at runtime.
15. Abstraction
What is Abstraction?
Abstraction means hiding the implementation details and showing only the essential features to the
user. It focuses on WHAT a class does, not HOW it does it. Achieved through abstract classes and
interfaces.

Abstract Class
A class declared with abstract keyword. Cannot be instantiated (cannot create objects directly). Can
have both abstract methods (no body) and concrete methods (with body).
abstract class Shape {
String colour;

Shape(String colour) { [Link] = colour; }

// Abstract method — must be overridden by subclasses


abstract double area();
abstract double perimeter();

// Concrete method — inherited as-is


void displayColour() {
[Link]("Colour: " + colour);
}
}

class Circle extends Shape {


double radius;
Circle(double r, String c) { super(c); [Link] = r; }

@Override
double area() { return [Link] * radius * radius; }

@Override
double perimeter() { return 2 * [Link] * radius; }
}

// Shape s = new Shape("red"); // ERROR — cannot instantiate abstract class


Shape s = new Circle(5, "red"); // OK — upcasting
[Link]("Area: %.2f%n", [Link]());

Interface
A completely abstract type (before Java 8) — all methods are implicitly abstract and public. A class
implements an interface and must provide implementations for all its methods. A class can implement
multiple interfaces.
interface Flyable {
// All fields are public static final (constants) by default
double MAX_ALTITUDE = 10000;

// All methods are public abstract by default


void fly();
void land();
}

interface Swimmable {
void swim();
}

// Implementing multiple interfaces


class Duck extends Animal implements Flyable, Swimmable {
@Override
public void fly() { [Link]("Duck is flying"); }

@Override
public void land() { [Link]("Duck landing"); }

@Override
public void swim() { [Link]("Duck is swimming"); }
}

Abstract Class vs Interface


Feature Abstract Class Interface
Instantiation Cannot create objects Cannot create objects
Methods Can have abstract + concrete Abstract by default;
default/static from Java 8
Variables Any type Only public static final
(constants)
Inheritance Single (one parent) Multiple (many interfaces)
Constructor Yes — can have No constructor
Access modifiers Any modifier on members Members are public by default
When to use Shared code + partial Define a contract / capability
abstraction
📌 Note: From Java 8 onwards, interfaces can have default methods (with body) and static
methods. From Java 9, they can also have private methods.
16. Non-Primitive Typecasting
What is Non-Primitive Typecasting?
For objects and references, casting refers to treating an object as its parent type or child type. There
are two kinds: Upcasting (widening) and Downcasting (narrowing).

Upcasting (Implicit)
Converting a child class reference to a parent class reference. Done automatically. Safe — no data
loss. The child object still exists, but only parent methods are visible via the reference.
class Animal {
void eat() { [Link]("Animal eating"); }
}

class Dog extends Animal {


void bark() { [Link]("Dog barking"); }
}

Dog dog = new Dog();


Animal a = dog; // Upcasting — automatic, no cast needed
// Animal a = (Animal) dog; // also valid but () not required

[Link](); // Works — Animal method


// [Link](); // COMPILE ERROR — Animal reference can't see bark()

Downcasting (Explicit)
Converting a parent class reference back to a child class reference. MUST be done explicitly. Can
cause ClassCastException at runtime if the actual object is not of the target type.
Animal a = new Dog(); // Upcast — a points to a Dog object
Dog d = (Dog) a; // Downcast — we know it's a Dog, so it's safe
[Link](); // Works!

// DANGEROUS DOWNCAST
Animal a2 = new Animal(); // actual object is Animal
Dog d2 = (Dog) a2; // ClassCastException at RUNTIME!

// SAFE PATTERN — always check with instanceof before downcasting


Animal ref = new Dog();
if (ref instanceof Dog) {
Dog safe = (Dog) ref;
[Link]();
}

instanceof Operator
Tests whether an object is an instance of a specific class or interface. Always use this before
downcasting to avoid ClassCastException.
Animal a = new Cat();
[Link](a instanceof Animal); // true
[Link](a instanceof Cat); // true
[Link](a instanceof Dog); // false

// Pattern matching (Java 16+)


if (a instanceof Cat cat) {
[Link](); // cat is already cast — no explicit cast needed
}

Casting with Interfaces


interface Printable { void print(); }

class Document implements Printable {


public void print() { [Link]("Printing doc"); }
public void save() { [Link]("Saving doc"); }
}

Printable p = new Document(); // Upcast to interface


[Link](); // Works
// [Link](); // ERROR — Printable doesn't have save()

Document doc = (Document) p; // Downcast back to Document


[Link](); // Now accessible
17. Object Class
What is the Object Class?
[Link] is the root of the Java class hierarchy. Every class in Java implicitly extends Object.
Therefore, every object is an instance of Object. It provides 11 methods that all classes inherit.

Key Methods of Object Class


Method Signature Default Behaviour Common Override?
toString() public String toString() Returns YES — return
ClassName@hashCod meaningful string
e (e.g.
Dog@1b6d3586)
equals() public boolean Compares memory YES — compare field
equals(Object obj) addresses (same as values
==)
hashCode() public int hashCode() Returns internal JVM YES — when equals()
address-based integer is overridden
getClass() public final Class<?> Returns runtime class Rarely — it's final
getClass() of the object
clone() protected Object Creates field-by-field When needed
clone() copy (shallow)
finalize() protected void finalize() Called by GC before Rarely
object is collected
(deprecated)
wait() / notify() Various Used for thread Rarely
synchronisation

Overriding toString()
class Student {
String name;
int rollNo;

Student(String name, int rollNo) {


[Link] = name;
[Link] = rollNo;
}

@Override
public String toString() {
return "Student[name=" + name + ", roll=" + rollNo + "]";
}
}

Student s = new Student("Ravi", 101);


[Link](s); // Calls toString() automatically
// Output: Student[name=Ravi, roll=101]
Overriding equals() and hashCode()
The contract: if two objects are equal by equals(), they must have the same hashCode(). Always
override hashCode() when you override equals().
class Point {
int x, y;
Point(int x, int y) { this.x = x; this.y = y; }

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Point)) return false;
Point other = (Point) obj;
return this.x == other.x && this.y == other.y;
}

@Override
public int hashCode() {
return 31 * x + y; // must be consistent with equals
}
}

Point p1 = new Point(3, 4);


Point p2 = new Point(3, 4);
[Link](p1 == p2); // false (different objects)
[Link]([Link](p2)); // true (same x, y)
18. String Class
Strings in Java
String is a class in [Link] package. String objects are immutable — once created, their content
cannot be changed. Strings are stored in the String Pool (a special area in heap memory).

Creating Strings
// Method 1: String Literal — uses String Pool
String s1 = "Hello";
String s2 = "Hello"; // s2 points to same object as s1 in pool

// Method 2: new keyword — creates a new object in heap


String s3 = new String("Hello");

// Comparing
[Link](s1 == s2); // true (same pool reference)
[Link](s1 == s3); // false (different heap object)
[Link]([Link](s3)); // true (same content)
📌 Note: Always use .equals() to compare String content, never == (which compares references).

Important String Methods


Method Description Example
length() Returns number of characters "Hello".length() → 5
charAt(i) Returns char at index i "Java".charAt(1) → 'a'
indexOf(str) First occurrence index of "Hello".indexOf("ll") → 2
substring
lastIndexOf(str) Last occurrence index "banana".lastIndexOf("a") → 5
substring(i) From index i to end "Hello World".substring(6) →
"World"
substring(i,j) From i to j (exclusive) "Hello".substring(1,4) → "ell"
toUpperCase() All uppercase "hello".toUpperCase() →
"HELLO"
toLowerCase() All lowercase "HELLO".toLowerCase() →
"hello"
trim() Remove leading/trailing spaces " hi ".trim() → "hi"
replace(old, new) Replace occurrences "cat".replace('c','b') → "bat"
contains(str) Check if contains substring "Hello".contains("ell") → true
startsWith(str) Check prefix "Java".startsWith("Ja") → true
endsWith(str) Check suffix "Java".endsWith("va") → true
isEmpty() Check if length == 0 "".isEmpty() → true
split(regex) Split into String array "a,b,c".split(",") → ["a","b","c"]
toCharArray() Convert to char[] "Hi".toCharArray() → ['H','i']
Method Description Example
valueOf(x) Convert any type to String [Link](42) → "42"
compareTo(str) Lexicographic comparison "abc".compareTo("abd") → -1
equalsIgnoreCase(str) Case-insensitive comparison "JAVA".equalsIgnoreCase("java
") → true
concat(str) Concatenate two strings "Hi".concat(" there") → "Hi
there"

String str = " Hello, Java World! ";

[Link]([Link]()); // "Hello, Java World!"


[Link]([Link]().toLowerCase()); // "hello, java world!"
[Link]([Link]().replace(",","")); // "Hello Java World!"
[Link]([Link]().split(" ").length);// 3

// String to int
int num = [Link]("42");

// int to String
String s = [Link](42);
String s2 = [Link](42);
String s3 = "" + 42; // implicit conversion

StringBuilder and StringBuffer


Since String is immutable, concatenating many strings creates many objects. StringBuilder and
StringBuffer are mutable alternatives — efficient for string manipulation.

Feature String StringBuilder StringBuffer


Mutable? No — immutable Yes — mutable Yes — mutable
Thread-safe? N/A No — single-threaded Yes — synchronised
use
Performance Slow for many Fast Slower than
concatenations StringBuilder
Use when Content doesn't Single thread, lots of Multi-threaded
change changes environment

StringBuilder sb = new StringBuilder();


[Link]("Hello");
[Link](", ");
[Link]("World");
[Link](5, "!"); // Insert at index 5
[Link](5, 6); // Delete index 5 to 6
[Link](); // Reverse content
[Link](0, 5, "Hi"); // Replace range

String result = [Link]();


[Link]([Link]()); // current length
String Immutability — Why it Matters
String s = "Hello";
s = s + " World"; // Does NOT modify original
// A NEW String object "Hello World" is created
// Old "Hello" becomes eligible for garbage collection

// This creates 5 string objects in memory:


String result = "";
for (int i = 0; i < 5; i++) {
result += i; // BAD — use StringBuilder instead
}

// Better:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
[Link](i); // Only one object mutated
}
String result2 = [Link]();

String Formatting
// [Link]() — like printf
String name = "Ravi";
int age = 21;
double gpa = 8.75;

String msg = [Link]("Name: %s, Age: %d, GPA: %.2f", name, age, gpa);
[Link](msg);
// Name: Ravi, Age: 21, GPA: 8.75

// Format specifiers:
// %s = String %d = integer
// %f = float/double %.2f = 2 decimal places
// %c = char %b = boolean
// %n = newline %10s = right-align in 10 chars
Quick Reference Summary

Topic Key Concepts to Remember


Tokens Keywords, Identifiers, Literals, Operators,
Separators, Comments
Data Types 8 primitives: byte short int long float double char
boolean. Default type for decimals = double; for
integers = int
Operators Arithmetic, Relational, Logical, Bitwise,
Assignment, Ternary, instanceof
Decision Making if / if-else / if-else-if / nested-if / switch (break
required to prevent fall-through)
Loops for (count known), while (pre-check), do-while
(runs at least once), for-each (arrays)
Jumping break (exit loop/switch), continue (skip iteration),
return (exit method)
Methods Overloading = same name diff params (compile-
time). Recursion needs base case. Varargs
with ...
static vs instance static = class-level shared; instance = per-object.
Static methods can't use this
Encapsulation private fields + public getters/setters. Validates
and controls data access
Has-A Composition (strong, object created inside) vs
Aggregation (weak, object passed in)
Inheritance extends keyword. super() calls parent constructor.
@Override annotation. final prevents override
Polymorphism Overloading = compile-time. Overriding +
upcasting = runtime. Parent ref → child object
Abstraction abstract class: partial abstraction. interface: full
contract. Class can implement multiple interfaces
Non-Prim Casting Upcasting = implicit (child→parent). Downcasting
= explicit + risky, use instanceof first
Object Class Root of all classes. Override toString(), equals(),
hashCode() for meaningful behaviour
String Immutable. Use equals() not ==. StringBuilder for
heavy manipulation. String Pool for literals

You might also like