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

Recap 04062025

Uploaded by

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

Recap 04062025

Uploaded by

truong giang
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

4/6/2025

3.5. Object and Class


OOP
4 principles:

Abstraction:

hide the complex implementation details and only show the essential information to user

Java supports abstraction by allowing creating abstract class and interface

Inheritance:

defines a IS-A relationship

allows reusing functionality and attributes

Polymorphism:

allows executing different behavior, for different types, which are determined at runtime

→ more flexible, easy to extend

Encapsulation:

2 meanings:

bundling of behaviors and attributes on a single object

hiding some fields and methods from public access (e.g: a class can have private
fields and they can only be accessed via getter/setter methods)

Constructor
Used to create instances of class

A class must have at least 1 constructor

the name of constructor is the same as class name

constructor has no return type

if coder doesn’t write any specific constructor for class, JVM will implicitly create default
constructor. Otherwise, the default constructor will not be created implicitly

The constructor can’t be used with keywords: abstract, static, final, native, synchronized

To create a new instance of class, using “new” keyword along with constructor

Demo constructor:

package objectnclass.constructor;

public class Student {


private String name;
//JVM will implicitly create default constructor for this class

4/6/2025 1
public String getName() {
return name;
}

public void setName(String name) {


this.name = name;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}

package objectnclass.constructor;

public class Person {


private String name;

public Person(String name) {


this.name = name;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}

package objectnclass.constructor;

public class Main {


public static void main(String[] args) {
Person p = new Person("Giang");
System.out.println(p.toString());

Student s = new Student();


s.setName("Giang");
System.out.println(s);
}
}

4/6/2025 2
Result:

Destructor
In Java, there’s no concept of destructor like in C++

But Java uses:

garbage collector: a mechanism in Java to delete objects which are no longer referenced →
prevent memory leaks

finalize() method:

any class has this method. It allows cleanup operations before the object is reclaimed
by garbage collector

deprecated since Java 9

can cause performance issues and deadlocks

AutoCloseable along with try-with-resources:

Demo destructor using AutoCloseable along with try-with-resources:

package objectnclass;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
* This class simulates the process of opening and closing resources (in this case: a BufferReader
*/
public class Resource implements AutoCloseable {
private BufferedReader reader;

public Resource(String filename) throws FileNotFoundException {


reader = new BufferedReader(new FileReader(filename));
System.out.println("Tài nguyên đã được mở.");
}

public String readLine() throws IOException {


return reader.readLine();

4/6/2025 3
}

@Override
public void close() throws IOException {
if (reader != null) {
reader.close();
System.out.println("Tài nguyên đã được đóng.");
}
}
}

package objectnclass;

import java.io.IOException;

public class TryWithResourcesExample {


public static void main(String[] args) {
String filename = "C:\\Users\\giang.hoang\\IdeaProjects\\Test\\src\\objectnclass\\example.txt"
try (Resource resource = new Resource(filename)) {
String line;
while ((line = resource.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Result:

Subclass
Aka child class

4/6/2025 4
Reuse functionality and attributes of parent class

Can add new attributes/methods of parent class or redefine methods of parent class

Demo subclass:

package objectnclass.subclass;

// Parent class
class Animal {
void eat() {
System.out.println("Động vật đang ăn.");
}
}

// Subclass
class Dog extends Animal {
void bark() {
System.out.println("Chó đang sủa.");
}
}

public class Main {


public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // inherited method from Animal class
dog.bark(); // method of Dog class
}
}

Result:

Nested class & Inner class


A class that is defined inside the body of another class

Used when classes are tightly coupled

4 different types of nested classes:

static nested class:

declared in class body.

this class can be accessed via class name identifier

4/6/2025 5
can only access static members of outer class

inner class:

declared in class body.

this class can only be accessed via an instance of the outer class

can access both static and non-static members of outer class

local class:

declared within method body

not have access modifier

can access local variables and method arguments, that are final or effectively final

can’t define static members

anonymous class:

unnamed class, declared and instantiated in same statement

can implement interface and extend class

Demo nested class:

1. static nested class:

package objectnclass.nestedclass;

class Outer {
private static String message = "Hello from Outer";

static class StaticNested {


void display() {
System.out.println(message);
}
}
}

public class StaticNestedClass {


public static void main(String[] args) {
Outer.StaticNested nested = new Outer.StaticNested(); //access static nested class via outer
nested.display();
}
}

Result:

4/6/2025 6
2. inner class:

package objectnclass.nestedclass;

class SecondOuter {
private String message = "Hello from Outer";

class Inner {
void display() {
System.out.println(message);
}
}
}

public class InnerClass {


public static void main(String[] args) {
SecondOuter outer = new SecondOuter();
SecondOuter.Inner inner = outer.new Inner();
inner.display();
}
}

Result:

3. local class:

package objectnclass.nestedclass;
class ThirdOuter {
void method() {
class Local {
void display() {
System.out.println("Inside Local class");
}
}
Local local = new Local();
local.display();
}
}

public class LocalClass {


public static void main(String[] args) {

4/6/2025 7
ThirdOuter outer = new ThirdOuter();
outer.method();
}
}

Result:

4. anonymous class:

package objectnclass.nestedclass;

interface Greeting {
void greet();
}

public class AnonymousClass {


public static void main(String[] args) {
Greeting greeting = new Greeting() {
public void greet() {
System.out.println("Hello from Anonymous class");
}
};
greeting.greet();
}
}

Result:

3.6. Method override, overload

4/6/2025 8
Method override
Aka runtime polymorphism

Redefine or extend an existing method in parent class

Java doesn’t support operator overriding

The method in subclass is the same as the method in parent class in terms of signature

Return type of method in subclass is either the same as that in parent class or subclass of that
in parent class

Access modifier of method in subclass must be larger than that in parent class

Exception of method in subclass mustn’t be new or larger than that in parent class

Constructor, private method, final method, static method can’t be overridden

Demo overriding:

package overloadnoverride;
class Animal {
// Method in superclass
public void sound() {
System.out.println("Animal makes a sound");
}
}

class Dog extends Animal {


// Overriding method in subclass
@java.lang.Override
public void sound() {
System.out.println("Dog barks");
}
}

public class Override {


public static void main(String[] args) {
Animal myAnimal = new Animal();
Animal myDog = new Dog();

myAnimal.sound(); // Outputs: Animal makes a sound


myDog.sound(); // Outputs: Dog barks
}
}

4/6/2025 9
Method overload
Often happens in a single class

Aka compile-time polymorphism

Overloading rules:

same name

different signature (with different parameters)

can return different return types

can have different access modifier

can throw different exception

Demo overloadding:

package overloadnoverride;

class Calculator {
// Overloaded method to add two integers
public int add(int a, int b) {
return a + b;
}

// Overloaded method to add three integers


public int add(int a, int b, int c) {
return a + b + c;
}

// Overloaded method to add two doubles


public double add(double a, double b) {
return a + b;
}
}
public class Overload {
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(2, 3)); // Calls add(int, int)
System.out.println(calc.add(2, 3, 4)); // Calls add(int, int, int)
System.out.println(calc.add(2.5, 3.5)); // Calls add(double, double)

4/6/2025 10
}
}

3.7. Mutable and Immutable object


Mutable Object
Its state can be modified after initialization

eg: StringBuilder, StringBuffer, java.util.Date,…

Provides methods to change status of object (e.g: setter)

Not safe to use in thread-safe environment

Effective in terms of performance when having to change multiple times

Example of mutable class:

package mutablenimmutable;
class MutablePerson {
private String name;
private int age;

public MutablePerson(String name, int age) {


this.name = name;
this.age = age;
}

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

public int getAge() {


return age;
}

4/6/2025 11
public void setAge(int age) {
this.age = age;
}
}

public class MutableExample {


public static void main(String[] args) {
MutablePerson person = new MutablePerson("Alice", 30);
System.out.println(person.getName() + " is " + person.getAge() + " years old.");
person.setAge(31); // change age
System.out.println(person.getName() + " is now " + person.getAge() + " years old.");
}
}

Immutable Object
Its state can’t be modified after initialization

eg: String, Integer, Float, BigDecimal,…

Not provide methods to change status of object

Safe to use in thread-safe environment

Easy to test and debug

Example of immutable class:

package mutablenimmutable;
final class ImmutablePerson {
private final String name;
private final int age;

public ImmutablePerson(String name, int age) {


this.name = name;
this.age = age;
}

public String getName() {


return name;
}

public int getAge() {

4/6/2025 12
return age;
}
}

public class ImmutableExample {


public static void main(String[] args) {
ImmutablePerson ip = new ImmutablePerson("Alice", 30);
System.out.println(ip.getName() + " is " + ip.getAge() + " years old.");
// ip.setAge(31); //compile error
}
}

String, StringBuilder and StringBuffer


String: immutable, thread-safe but less efficient in terms of memory and performance

StringBuilder: mutable, not thread-safe, more memory-efficient than String

StringBuffer: mutable, thread-safe, less efficient than StringBuilder in terms of memory and
performance

Demo String, StringBuilder, and StringBuffer:

package mutablenimmutable;
public class HandleStringExample {
// Concatenates to String
public static void concat1(String s1)
{
s1 = s1 + "world";
}

// Concatenates to StringBuilder
public static void concat2(StringBuilder s2)
{
s2.append("world");
}

// Concatenates to StringBuffer
public static void concat3(StringBuffer s3)
{
s3.append("world");

4/6/2025 13
}

// Main driver method


public static void main(String[] args)
{
// Custom input string
// String 1
String s1 = "Hello";
concat1(s1);
System.out.println("String: " + s1);// s1 is not changed

// String 2
StringBuilder s2 = new StringBuilder("Hello");
concat2(s2);
System.out.println("StringBuilder: " + s2); // s2 is changed

// String 3
StringBuffer s3 = new StringBuffer("Hello");
concat3(s3);
System.out.println("StringBuffer: " + s3);// s3 is changed
}
}

3.8. Boxing and Unboxing


Boxing: conversion of a primitive value into an object of corresponding wrapper class

Java supports autoboxing

Besides, can boxing by using valueOf or wrapper constructor (deprecated since Java 9):

Integer boxedInt = Integer.valueOf(15); //boxing (unnecessary)


// Integer deprecatedBoxing = new Integer(15); //deprecated

Unboxing: conversion of a object of a wrap class into its corresponding primitive value

like boxing, Java also supports auto unboxing

besides, can unboxing by using intValue

Integer boxedInt = Integer.valueOf(15); //boxing (unnecessary)


// Integer deprecatedBoxing = new Integer(15); //deprecated
int unboxedInt = boxedInt.intValue(); //unnecessary

Primitive Type Wrapper Class

boolean Boolean

byte Byte

char Character

4/6/2025 14
float Float

int Integer

long Long

short Short

double Double

Compare primitive and wrapper:

Aspects Primitive Type Wrapper Class

Object which inherits from


Nature Basic data type, not object
java.lang.Object

Faster because we can access it directly Slower because we access it


Execution speed
through stack through heap

Memory size More efficient Less efficient

Can be null? No Yes

Can be used in
No Yes (e.g: List , Map , ...)
Collections?

3.9. Exception
Exception: unwanted or unexpected event that occurs during runtime and disrupts normal flows
of program

If an exception occurs and is not handled, the program terminates abruptly and the code after it
will never execute.

Some common exceptions: ClassNotFoundException, IOException, SQLException,


RemoteException, ….

4/6/2025 15
Checked Exceptions: checked at compile-time → compile-time exceptions

Unchecked Exceptions: not checked at compile-time → even if we didn’t handle unchecked


exception, the program would not give compilation error

User-defined Exceptions:

package exception;

// Custom Checked Exception


class MyException extends Exception {
public MyException(String m) {
super(m);
}
}

// Using the Custom Exception


public class MyExceptionExample {
public static void validate(int age) throws MyException {
if (age < 18) {
throw new MyException("Age must be 18 or above.");
}
System.out.println("Valid age: " + age);
}

public static void main(String[] args) {


try {
validate(12);
} catch (MyException e) {
System.out.println("Caught Exception: " + e.getMessage());
}
}
}

4/6/2025 16
3.10. Interface, Abstract Class and Enum
Interface
A reference type, similar to a class but not a class

Can’t be instantiated directly, not have constructors

Interfaces and its methods are abstract by default → no need to declare interface with
“abstract” keyword

Methods of interface are public and abstract by default (before Java 8)

Java 8 introduced default and public static methods (these methods are concrete methods)

Java 9 introduced private methods, both static and non-static (these methods are concrete
methods)

Fields of interface are public static final by default

Example of interface:

package abstractinterface;
interface IAnimal {
void makeSound(); // phương thức trừu tượng
}
class Cat implements IAnimal {
@Override
public void makeSound() {
System.out.println("Meow! Meow!");
}
}
class Cow implements IAnimal {
@Override
public void makeSound() {
System.out.println("Moo! Moo!");
}
}
public class InterfaceExample {
public static void main(String[] args) {
IAnimal myCat = new Cat(); // using interface as reference type
IAnimal myCow = new Cow();

myCat.makeSound();

4/6/2025 17
myCow.makeSound();

}
}

Abstract class
An incomplete class, acting like a blueprint for other classes

Can’t be instantiated directly, but can still have constructors, which will be called by its
subclasses during their construction

Can contain both abstract methods (methods with no implementation) and concrete methods
(methods with an implementation)

Example of abstract class:

package abstractinterface;

abstract class Animal {


private String size;
private double weight;

public Animal(String size, double weight) {


this.size = size;
this.weight = weight;
}
public abstract void move(String speed);
public void makeNoise(){
System.out.println("Animal is making noise");
}
}
class Dog extends Animal {

public Dog(String size, double weight) {


super(size, weight);
}

@Override
public void move(String speed) {
System.out.println("Dog is moving at " + speed + " speed");
}

4/6/2025 18
@Override
public void makeNoise() {
super.makeNoise();
}
}
public class AbstractClassExample {
public static void main(String[] args) {
Dog dog = new Dog("small", 15);
dog.move("slow");
dog.makeNoise();

}
}

Why still use interface when can use abstract class instead?
A class can only extend one (abstract) class, but can implement multiple interfaces → using
interfaces will be more flexible

Interfaces represent capability or behavior, not structure or inheritance hierarchy

Interfaces are more flexible and less risky to change

Interfaces are often used in frameworks → loose coupling, easy testing

Enum
Special data type that contains predefined constants

An enum type is like an array, but its elements are known, not changeable. Each element can be
accessed with a constant name, instead of index

package enumdemo;
enum DayOfTheWeek {
SUN, MON, TUES, WED, THURS, FRI, SAT
}
public class EnumExample {
public static void main(String[] args) {
DayOfTheWeek weekDay = DayOfTheWeek.TUES;
System.out.println(weekDay); //TUES

4/6/2025 19
System.out.printf("Name is %s, Ordinal value = %d%n", weekDay.name(), weekDay.ordinal())
}
}

4/6/2025 20

You might also like