Java Classes
OOP Principles
- Encapsulation
- Inheritance
- Polymorphism
- Encapsulation: Bundling data and methods together
- Inheritance: Deriving new classes from existing ones
- Polymorphism: One interface, multiple behaviors
Why OOP ?
- Code reusability
- Modularity and maintainability
- Real-world modeling
Encapsulation
- Attributes: Fields
- define the state of an object
- Methods: Behaviors
- define the actions an object can perform
- in relation to other classes
- Hiding internal details and exposing only necessary information
A class 🚲
Bike.java
public class Bike {
// Attributes
private String color;
private int speed;
private boolean pannierRacks;
// Constructor
public Bike(String color, boolean pannierRacks) {
this.color = color;
this.speed = 0;
this.pannierRacks = pannierRacks;
}
// Method
public void accelerate(int increment) {
if (increment > 0) {
this.speed += increment;
}
}
// Getter
public int getSpeed() {
return this.speed;
}
}details after
Attributes
Bike.java
public class Bike {
// Attributes
private String color = "yellow"; // default value if not specified by the constructor
private int speed;
private boolean pannierRacks;
private static int nbBikes = 0;
}- static: class attribute
- usually private attributes
- setters and getters next
Reminder: Attributes Accessiblility
| Modifier | Same Class | Same Package | Subclasses | Everywhere |
|---|---|---|---|---|
| public | ✅ | ✅ | ✅ | ✅ |
| protected | ✅ | ✅ | ✅ | ❌ |
| default (no modifier) | ✅ | ✅ | ❌ | ❌ |
| private | ✅ | ❌ | ❌ | ❌ |
Constructor
Bike.java
public class Bike {
public Bike(String color, boolean pannierRacks) {
this.color = color;
this.speed = 0;
this.pannierRacks = pannierRacks;
}
}this: Refers to the current object
- Name of a Contructor: same as class name
- Generally public
- Private Contructor ?
- Singleton Pattern (public static SingletonClass getInstance())
- Uninstantiable Classes: class that simply contains static methods
- Private Constructor called by Public Constructor
Create a Bike Object
Bike greenBike = new Bike("Green", true);- Bike: type of the variable
- greenBike: name of the variable
- new: Memory allocation
- Bike(…): constructor call
- Java only uses positional arguments
- You can create several constructors ≠ Python
Default Constructor
- If no constructor is provided
Bike myBike = new Bike();- with default values
- color: null
- pannierRacks: false
- Error if another constructor is provided
Create a copy
Bike greenBike = new Bike("Green", true);
Bike otherBike = greenBike;- otherBike is it a copy of greenBike?
- No, it refer to the same Bike object
- How to create a copy?
// Copy constructor
public Bike(Bike other) {
...
}
Bike greenBike = new Bike("Green", 25, true);
Bike copiedBike = new Bike(greenBike);Call a method
// Create a Bike object calling the constructor
Bike greenBike = new Bike("Green", true);
// Call methods
greenBike.accelerate(5);
System.out.println(greenBike.getSpeed());- accelerate(int) -> void
- getSpeed() -> int
Main method
- Entry point
- Generally in a class called Main
public static void main(String[] args) {
// Program logic here
}- public: Makes the method accessible from anywhere (required for JVM to call it)
- static: Allows calling the method without creating an instance of the class.
- void: The method does not return any value.
- main: The method name that JVM looks for to start execution.
- String[]: args Array of command-line arguments passed when running the program
Using args
String[] args: arguments passed when running the program
Main.java
public static void main(String[] args) {
int limit = Integer.parseInt(args[0]);
for (int i = 0; i <= limit; i++) {
System.out.println(i);
}
}javac Main.javajava Main 8
Inheritance
Parent class
Vehicle.java
public class Vehicle {
protected String color;
protected int speed;
public Vehicle(String color) {
this.color = color;
this.speed = 0;
}
}Subclass
extends: inheritsuper(): constructor of the parent classsuper.foo(): method foo() of the parent class- super does not allow access to the private attributes of the parent class
Bike.java
public class Bike extends Vehicle {
private boolean pannierRacks;
// Constructor
public Bike(String color) {
super(color);
this.pannierRacks = pannierRacks;
}
}- Multiple-inheritance is forbidden in Java
- Use Interfaces
- Declare methods to be implemented.
Abstract
- abstract classes: cannot be instantiated
- abstract methods: Declared without implementation, must be overridden by subclasses
Vehicle.java
public abstract class Vehicle {
protected String color;
protected int speed;
public Vehicle(String color) {
this.color = color;
this.speed = 0;
}
public abstract void honk(); // abstract method to be implemented in subsclasses
public void accelerate(int increment) {
this.speed += increment;
}
}Questions:
- Is it possible to create a final abstract class?
- Private abstract method?
Override method
Bike.java
public class Bike extends Vehicle {
private boolean pannierRacks;
// Constructor
public Bike(String color) {
super(color);
this.pannierRacks = pannierRacks;
}
@Override
public abstract void honk(){
System.out.println("Dring")
}
@Override
public void accelerate(int increment) {
this.speed += increment + 2;
}- You must override abstract methods
- You can override other methods
- Override final method?
Polymorphism
Substitution
Main.java
Bike bike1 = new Bike();
Bike bike2 = new Bike();
Scooter scooter1 = new Scooter();
Scooter scooter2 = new Scooter();
List<Vehicle> vehicles = List.of(bike1, bike2, scooter1, scooter2);
// Accelerate all vehicles
for (Vehicle vehicle : vehicles) {
vehicle.accelerate(10);
}subclass provides a specific implementation of a method that is already defined in its superclass
Overloading
Bike.java
public class Bike extends Vehicle {
private boolean pannierRacks;
...
public void accelerate(int increment) {
this.speed += increment;
}
public void accelerate() {
this.speed += 5;
}
public void accelerate(double increment) {
this.speed += increment.intValue();
}class has multiple methods with the same name but different parameters
JavaDoc
- Clarity: Provides clear and consistent documentation
- Maintainability: Makes it easier to understand and maintain code
- Accessibility: Generates HTML documentation that can be easily shared and viewed
Javadoc comments are enclosed in /** and */.
Placed immediately before the element being documented (class, method, field, etc.)
Example
Bike.java
/**
* Represents a Bike, a type of Vehicle.
*/
public class Bike extends Vehicle {
private boolean pannierRacks;
/**
* Constructs a Bike with the given color
*/
public Bike(String color) {
super(color);
this.pannierRacks = false;
}
/**
* Produces the sound of a bike's honk (dring).
*/
@Override
public void honk() {
System.out.println("Dring");
}
/**
* Accelerates the bike by the given increment, plus an additional 2 units.
*
* @param increment The amount to increase the speed by.
*/
@Override
public void accelerate(int increment) {
this.speed += increment + 2;
}
/**
* Checks if the bike has pannier racks.
*
* @return true if the bike has pannier racks, false otherwise.
*/
public boolean hasPannierRacks() {
return pannierRacks;
}Tags
@author: Author of the class.@version: Version of the class.@param: Description of a method parameter.@return: Description of a method’s return value.@throws: Description of an exception that a method might throw.@see: Cross-reference to other classes or methods.@deprecated: Indicates that a method or class is deprecated.