Abstract Classes
Sometimes you want a class that's a blueprint: it defines what child classes MUST do, but it can't be used on its own. That's an abstract class
Think of it this way: "Vehicle" is a concept. You can't just build a generic "vehicle". You build a sports car, a motorcycle, a truck. But they all share the idea of being a vehicle. In Java, you'd make Vehicle abstract
abstract class Vehicle {
String name;
Vehicle(String name) {
this.name = name;
}
abstract int topSpeed(); // no body! children MUST implement this
void honk() {
System.out.println(name + " goes BEEP!");
}
}
Two key things here:
- The class is marked
abstract, so you CANNOT donew Vehicle("something") - The method
topSpeed()is markedabstract: it has NO body (no curly braces), just a semicolon. Any non-abstract child MUST provide the body
public class Main {
public static void main(String[] args) {
Vehicle v = new Vehicle("test"); // COMPILER ERROR! Can't instantiate abstract class
}
}
It's like trying to buy a "vehicle" at a dealership. The salesperson would say "which KIND of vehicle?" You need a concrete type
A child class that extends an abstract class MUST implement all abstract methods, or it has to be abstract itself
abstract class Vehicle {
String name;
Vehicle(String name) { this.name = name; }
abstract int topSpeed();
}
class SportsCar extends Vehicle {
SportsCar(String name) {
super(name);
}
@Override
int topSpeed() {
return 240;
}
}
class Motorcycle extends Vehicle {
Motorcycle(String name) {
super(name);
}
@Override
int topSpeed() {
return 200;
}
}
public class Main {
public static void main(String[] args) {
SportsCar infernus = new SportsCar("Infernus");
Motorcycle angel = new Motorcycle("Angel");
System.out.println(infernus.name + ": " + infernus.topSpeed() + " km/h");
System.out.println(angel.name + ": " + angel.topSpeed() + " km/h");
}
}
Output
Infernus: 240 km/h
Angel: 200 km/h
An abstract class can have both abstract methods (that children must implement) and regular methods (that children inherit for free)
abstract class Character {
String name;
int health;
Character(String name, int health) {
this.name = name;
this.health = health;
}
// Abstract - each character fights differently
abstract void attack();
// Concrete - all characters take damage the same way
void takeDamage(int amount) {
health -= amount;
System.out.println(name + " takes " + amount + " damage! HP: " + health);
}
}
Tommy Vercetti and Lance Vance would both extend Character. They'd each have their own attack() style, but takeDamage() works the same for everyone
When to use abstract class vs regular class?
Use a regular class when it makes sense to create objects of that type directly. A Car is a real thing, you can create one
Use an abstract class when the class is just a concept or category. "Vehicle" is abstract: there's no such thing as a generic vehicle. "Character" could go either way depending on your design
The rule of thumb: if you'd never want someone to write new YourClass(), make it abstract
Mission: Tommy's Fleet
Tommy has several vehicles in his garage, each with its own top speed. He needs a report showing every vehicle and its speed, but "Vehicle" itself is just a concept, not something you can build directly.
Create an abstract class Vehicle with a String name field, a constructor, and an abstract method topSpeed() that returns an int. Then create two concrete classes:
SportsCar:topSpeed()returns240Motorcycle:topSpeed()returns200
In main, store the two names in variables name1 and name2 (start with "Infernus" and "Angel"). Create a SportsCar from name1 and a Motorcycle from name2. Print each in the format Name: X km/h.
Example
Infernus: 240 km/h
Angel: 200 km/h