Object-Oriented Programming in Java
Welcome to our lesson on Object-Oriented Programming (OOP) in Java! If you’re coming from JavaScript, you’ll find many similarities in the syntax, especially if you’re familiar with ES6+ classes. However, Java’s OOP model is more rigid and class-based, while JavaScript’s classes are still built on its prototype-based system. Let’s explore how Java handles OOP concepts, drawing comparisons with JavaScript’s class syntax to help you quickly grasp these ideas.
Classes and Objects: Java vs JavaScript
Both Java and modern JavaScript use the class
keyword to define classes, but there are some key differences:
// Java
public class Car {
private String model;
private int year;
public Car(String model, int year) {
this.model = model;
this.year = year;
}
}
Car myCar = new Car("Tesla", 2023);
// JavaScript
class Car {
constructor(model, year) {
this.model = model;
this.year = year;
}
}
const myCar = new Car('Tesla', 2023);
While the syntax looks similar, Java requires explicit declaration of properties and their types. The public
and private
keywords in Java are access modifiers, which we’ll discuss shortly.
Constructors and the new
Keyword
Constructors work similarly in both languages, but Java constructors must have the same name as the class:
// Java
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
}
Person john = new Person("John");
// JavaScript
class Person {
constructor(name) {
this.name = name;
}
}
const john = new Person('John');
The new
keyword instantiates a new object based on the class definition in both languages.
Access Modifiers
Java uses access modifiers to control the visibility of class members:
public class Employee {
private String name; // Only accessible within this class
public int id; // Accessible from anywhere
protected double salary; // Accessible in same package and subclasses
}
JavaScript doesn’t have built-in access modifiers, but it does offer private fields with the #
prefix in recent versions:
class Employee {
#name; // Private field
id; // Public field
constructor(name, id) {
this.#name = name;
this.id = id;
}
}
Inheritance and the extends
Keyword
Both Java and JavaScript use the extends
keyword for inheritance:
// Java
public class Animal {
public void makeSound() {
System.out.println("Some sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
// JavaScript
class Animal {
makeSound() {
console.log('Some sound');
}
}
class Dog extends Animal {
makeSound() {
console.log('Woof!');
}
}
The main difference is that Java uses the @Override
annotation to explicitly indicate method overriding.
Interfaces and Multiple Inheritance
Java uses interfaces to achieve a form of multiple inheritance:
// Java
interface Swimmable {
void swim();
}
interface Flyable {
void fly();
}
public class Duck implements Swimmable, Flyable {
public void swim() {
System.out.println("Duck is swimming");
}
public void fly() {
System.out.println("Duck is flying");
}
}
JavaScript doesn’t have a direct equivalent to interfaces. Although not seen often in the wild, you can achieve similar functionality using the mixin pattern:
// JavaScript
const Swimmable = {
swim() {
console.log('Swimming');
},
};
const Flyable = {
fly() {
console.log('Flying');
},
};
class Duck {}
Object.assign(Duck.prototype, Swimmable, Flyable);
Abstract Classes
Java supports abstract classes, which are a middle ground between interfaces and concrete classes:
// Java
abstract class Shape {
abstract double area();
public void display() {
System.out.println("This is a shape");
}
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
double area() {
return Math.PI * radius * radius;
}
}
JavaScript doesn’t have built-in support for abstract classes, but you can simulate them:
// JavaScript
class Shape {
constructor() {
if (new.target === Shape) {
throw new TypeError('Cannot instantiate abstract class');
}
}
area() {
throw new Error("Method 'area()' must be implemented");
}
display() {
console.log('This is a shape');
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() {
return Math.PI * this.radius ** 2;
}
}
Conclusion
In this lesson, we’ve explored the core concepts of Object-Oriented Programming in Java, drawing parallels with JavaScript’s class syntax. We’ve covered classes and objects, constructors, access modifiers, inheritance, interfaces, and abstract classes. While both languages now use similar syntax for defining classes, Java’s OOP model is more rigid and provides stronger encapsulation and type safety.
As you move forward, remember that JavaScript’s class syntax is built on top of its prototype-based inheritance system, while Java’s class-based system is fundamental to the language. This understanding will help you navigate the differences between the two languages as you continue to learn Java.
Next, we’ll dive into the Java Collections Framework, where you’ll learn about Java’s powerful data structures that build upon these OOP principles. Get ready to explore Lists, Sets, and Maps – Java’s equivalents to JavaScript’s arrays and objects, but with some exciting twists!