Abstract Classes and Interfaces in Java
Use abstract classes and interfaces to say what a class must do while leaving how it does it to the subclasses.
Learning objectives
- βExplain abstraction: show what an object does and hide how it does it
- βWrite abstract classes that mix abstract and normal methods
- βDefine and implement interfaces, including several in one class
- βChoose between an abstract class and an interface
π‘ Key points
- Abstraction means hiding the details and showing only the essentials. Java does it with abstract classes and interfaces.
- An abstract class is marked abstract and cannot be created with new. It can still have fields, constructors and normal methods.
- An abstract method has no body and ends with a semicolon. A concrete subclass must override every abstract method, or be declared abstract itself.
- An interface lists methods that a class promises to provide. The class writes implements and must define each abstract method as public.
- Interface methods are public and abstract by default, and interface variables are always public static final constants.
- A class can extend only one class but can implement many interfaces. This is how Java allows multiple inheritance of type.
- Since Java 8, an interface can also contain default methods (with a body) and static methods.
π» Code examples(5)
abstract class Shape {
String name;
Shape(String name) {
this.name = name;
}
abstract double area(); // no body
void show() { // normal method
System.out.println(name + ": " + area());
}
}
class Square extends Shape {
double side;
Square(double side) {
super("Square");
this.side = side;
}
@Override
double area() {
return side * side;
}
}
public class AbstractDemo {
public static void main(String[] args) {
// new Shape("x"); // error: abstract
Shape s = new Square(4);
s.show();
}
}
Square: 16.0
interface Payable {
double GST = 0.18; // public static final
double amount(); // public abstract
}
class Invoice implements Payable {
double price;
Invoice(double price) {
this.price = price;
}
@Override
public double amount() {
return price + price * GST;
}
}
public class InterfaceDemo {
public static void main(String[] args) {
Payable p = new Invoice(1000);
System.out.println("Pay Rs." + p.amount());
System.out.println(Payable.GST);
}
}
Pay Rs.1180.0 0.18
interface Camera {
void takePhoto();
}
interface MusicPlayer {
void playSong(String song);
}
class SmartPhone implements Camera, MusicPlayer {
@Override
public void takePhoto() {
System.out.println("Click! Photo saved");
}
@Override
public void playSong(String song) {
System.out.println("Playing " + song);
}
}
public class PhoneDemo {
public static void main(String[] args) {
SmartPhone phone = new SmartPhone();
phone.takePhoto();
phone.playSong("Jai Ho");
Camera cam = phone; // seen as just a Camera
cam.takePhoto();
// cam.playSong("x"); // error: not a Camera job
}
}
Click! Photo saved Playing Jai Ho Click! Photo saved
interface Greeter {
String name();
default void greet() {
System.out.println("Namaste, " + name() + "!");
}
static void rule() {
System.out.println("Greet everyone politely");
}
}
class Student implements Greeter {
public String name() {
return "Priya";
}
}
class Teacher implements Greeter {
public String name() {
return "Mrs. Rao";
}
@Override
public void greet() {
System.out.println("Good morning from "
+ name());
}
}
public class DefaultDemo {
public static void main(String[] args) {
new Student().greet();
new Teacher().greet();
Greeter.rule();
}
}
Namaste, Priya! Good morning from Mrs. Rao Greet everyone politely
interface Refundable {
void refund(double amt);
}
abstract class Payment {
double amount;
Payment(double amount) {
this.amount = amount;
}
abstract String mode();
void receipt() {
System.out.println("Paid Rs." + amount
+ " via " + mode());
}
}
class UpiPayment extends Payment
implements Refundable {
UpiPayment(double amount) { super(amount); }
@Override
String mode() { return "UPI"; }
@Override
public void refund(double amt) {
System.out.println("Refunded Rs." + amt);
}
}
class CashPayment extends Payment {
CashPayment(double amount) { super(amount); }
@Override
String mode() { return "Cash"; }
}
public class Checkout {
public static void main(String[] args) {
Payment[] list = {
new UpiPayment(499),
new CashPayment(150)
};
for (Payment p : list) {
p.receipt();
if (p instanceof Refundable) {
((Refundable) p).refund(p.amount);
}
}
}
}
Paid Rs.499.0 via UPI Refunded Rs.499.0 Paid Rs.150.0 via Cash
π― Practice
Q1. Can you create an object of an abstract class?+
No. new Shape() gives 'Shape is abstract; cannot be instantiated'. Create an object of a concrete subclass instead; you can still store it in a Shape reference.
Q2. Dog extends the abstract class Animal, which has abstract void sound(). Dog does not define sound(). What happens?+
A compile error: 'Dog is not abstract and does not override abstract method sound() in Animal'. Either write sound() in Dog or declare Dog abstract too.
Q3. Why must a class write public when it implements an interface method?+
Interface methods are public by default, and an overriding method cannot have weaker access. Leaving out public gives default access, which the compiler rejects.
Q4. Can an abstract class have a constructor? Why would it need one?+
Yes. It runs when a subclass object is created (through super(...)) and sets up the shared fields, like name in Shape.
Q5. Bird and Aeroplane should both have fly(). Abstract class or interface?+
An interface, say Flyable. Birds and aeroplanes share an ability, not a family, and each may already need to extend a different class.
π Notes
Abstract class vs interface
| Abstract class | Interface | |
|---|---|---|
| Methods | Abstract and normal | Abstract by default, plus default and static (Java 8+) |
| Variables | Any fields | Only public static final constants |
| Constructor | Allowed | Not allowed |
| A class can use | One (extends) | Many (implements) |
| Best for | Related classes sharing code (IS-A) | Unrelated classes sharing an ability (CAN-DO) |
Interfaces you already use
String implements the interface Comparable<String>. That is why compareTo() from Day 11 exists, and why Java can sort a list of names (Day 20). ArrayList implements the List interface, so you will often see:
List<String> names = new ArrayList<>();
That is upcasting to an interface type, exactly like Animal a = new Dog();.
Common mistakes
- Forgetting
publicon an implementing method. You get amount() in Invoice cannot implement amount() in Payable (attempting to assign weaker access privileges). - Writing
newon an interface or abstract class.new Payable()andnew Shape(...)are both errors. - Giving an abstract method a body.
abstract void f() { }gives abstract methods cannot have a body. - Mixing up
extendsandimplements. A class extends a class and implements an interface. One interface extends another interface. - Trying to change an interface constant.
Payable.GST = 0.2;fails, because it isfinal.
Next: Day 17, Encapsulation and Access Modifiers. You will learn how private, protected and public protect an object's data.