Java Basics  «Prev  Next»

Lesson 1

Java Object-Oriented Programming

This course introduces object-oriented programming (OOP) in modern Java (Java 17/21+), then applies those ideas across concurrency and networking. You’ll learn how classes, interfaces, and packages work together; how to design with composition and inheritance; and how to handle errors with exceptions.

Course goals

By the end, you will be able to:

  1. Model real-world problems using classes, interfaces, and packages.
  2. Use encapsulation to protect state and enforce invariants.
  3. Design with inheritance and composition, knowing when to choose each.
  4. Throw, catch, and propagate exceptions responsibly.
  5. Write multitasking programs with executors and futures.
  6. Perform basic networking with java.net and java.net.http.

Core OOP pillars in Java


Encapsulation example (validated, idiomatic)

Encapsulation guards state and funnels changes through business rules. Prefer throwing exceptions over printing errors.

public final class Person {
  private String name;
  private int age;

  public Person(String name, int age) {
    setName(name);
    setAge(age);
  }

  public String getName() { return name; }

  public void setName(String name) {
    if (name == null || name.isBlank()) {
      throw new IllegalArgumentException("name must be non-blank");
    }
    this.name = name;
  }

  public int getAge() { return age; }

  public void setAge(int age) {
    if (age < 0 || age > 149) {
      throw new IllegalArgumentException("age must be 0..149");
    }
    this.age = age;
  }
}

Tip: When objects should never change after construction, make fields private final and drop setters. Consider a record for simple data carriers:

public record Point2D(int x, int y) { }

Inheritance with classes

Inheritance lets a subclass reuse and specialize a superclass’s state and behavior. Use it when there is a clear “is-a” relationship and you want to leverage polymorphism.

Simple inheritance + overriding

class Vehicle {
  protected int speed; // demo only; prefer private + getters/setters

  public void accelerate(int delta) { speed += delta; }
  public String info() { return "Vehicle@" + speed + "km/h"; }
}

class Car extends Vehicle {
  private int gear = 1;

  @Override
  public void accelerate(int delta) {
    super.accelerate(delta);
    if (speed > 0 && gear < 6) gear = Math.min(6, 1 + speed / 20);
  }

  @Override
  public String info() { return "Car@" + speed + "km/h, gear " + gear; }
}

public class Demo {
  public static void main(String[] args) {
    Vehicle v = new Car();         // polymorphism: reference type = Vehicle
    v.accelerate(35);
    System.out.println(v.info());  // calls Car.info()
  }
}

When to prefer composition

Favor composition when behavior varies independently or “is-a” doesn’t hold. The class has a collaborator instead of is one.

interface Engine { int torque(); }
final class ElectricMotor implements Engine { public int torque() { return 320; } }
final class TurboDiesel   implements Engine { public int torque() { return 420; } }

final class Truck {
  private final Engine engine; // composition
  Truck(Engine engine) { this.engine = engine; }
  int pullingPower()  { return engine.torque(); }
}

Exceptions: communicating failure

import java.nio.file.*;
import java.io.*;

public class ReaderExample {
  public static String readFirstLine(Path path) {
    try (BufferedReader br = Files.newBufferedReader(path)) {
      return br.readLine();
    } catch (IOException ioe) {
      throw new UncheckedIOException("Failed to read " + path, ioe);
    }
  }
}

Multitasking and networking preview

We’ll use the Concurrency API and the modern HTTP client.

import java.net.http.*;
import java.net.URI;
import java.util.concurrent.*;

public class FetchTitle {
  public static void main(String[] args) throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    CompletableFuture<String> title =
      client.sendAsync(
              HttpRequest.newBuilder(URI.create("https://example.com")).GET().build(),
              HttpResponse.BodyHandlers.ofString())
            .thenApply(HttpResponse::body)
            .thenApply(body -> body.substring(0, Math.min(80, body.length()))); // demo

    System.out.println(title.get(3, TimeUnit.SECONDS));
  }
}


Certification-style checkpoints

JavaDeploy series

The Introduction to Java sequence starts here, advances into GUI development, and continues with modern topics across this site. You will build from small console programs to modular applications that use concurrency and HTTP. Expect short, focused exercises and review questions at the end of each lesson.

Key takeaways


SEMrush Software