[5] Intro to Object-oriented programming - Abstract classes and Interfaces in Java
🤫

[5] Intro to Object-oriented programming - Abstract classes and Interfaces in Java

Date
Dec 5, 2022
Tags
OOP
JAVA
programming
The following are my notes on OOP course (Object-oriented programming) based on Kunal Kashwaha’s lectures on YouTube (link in the reference section)

Abstract Classes

Abstract classes are a way of achieving abstraction - which is the process of hiding complexity and only showing functionality to the user.
Any class which has one or more abstract methods will need to be declared as an abstract class in java.
The abstract methods will need to be overridden by the child classes!

the abstract keyword

If you want to force the child class to override specific methods, those methods can be defined as abstract.
abstract type name(parameter-list);
abstract methods have no implementation specified in the parent class, thus it is the responsibility of the child class.
 

points to remember:

  • No objects of an abstract class can be created.
  • You can have abstract and non-abstract methods in an abstract class
  • You cannot declare constructors as abstract, or static methods as abstract, but you can have just normal constructors or methods.
  • You can declare static methods in abstract class.
  • You can have final methods which will force the child class not to change the body of the method.
  • Any child class of an abstract class must either implement all of the abstract methods in the parent class or be declared as abstract itself.
 
Abstract class objects can be used as a reference! But cannot be used to instantiate an object
(because Java’s approach to run-time polymorphism is implemented through the use of parent class references.)
Example:
Parent class
abstract class ECar{ abstract void start(); }
Child class
class Tesla extends ECar{ @Override void start() { System.out.println("Tesla started safely."); } public static void main(String args[]){ // Reference of ECar used. ECar obj = new Tesla(); obj.start(); } } // OUTPUT Tesla started safely.
 

Abstract classes vs Interfaces

Abstract classes
Interfaces
Abstract class can have abstract and non-abstract methods.
Interface can have only abstract methods.
An abstract class may contain non-final variables.
Variables declared in a Java interface are by default final.
Abstract class can have final, non-final, static and non-static variables
Interface has only static and final variables.
Abstract class can provide the implementation of interface.
Interface can’t provide the implementation of abstract class.
Abstract class can be extended using keyword “extends”.
A Java interface can be implemented using keyword “implements
Abstract class can extend 1 Java class and implement multiple Java interfaces.
An interface can extend another Java interface only,
A Java abstract class can have class members like private, protected, etc.
Members of a Java interface are public by default.

Example to understand Abstract classes

Parent Abstract class
public abstract class BaseFileReader { protected Path filePath; public Path getFilePath() { return filePath; } protected abstract String mapFileLine(String line); }
 
Child class 1: converts a file's contents to lowercase
public class LowercaseFileReader extends BaseFileReader { public LowercaseFileReader(Path filePath) { super(filePath); } @Override public String mapFileLine(String line) { return line.toLowerCase(); } }
Child class 2: converts a file's contents to uppercase
public class UppercaseFileReader extends BaseFileReader { public UppercaseFileReader(Path filePath) { super(filePath); } @Override public String mapFileLine(String line) { return line.toUpperCase(); } }

Interfaces in Java

Interfaces: a blueprint of a behavior.
Interfaces specify only what the class is doing, not how it is doing it.
The problem with MULTIPLE INHERITANCE:
Two classes may define different ways of doing the same thing, so the child class cannot choose what to perform!
A class can implement more than one interface.
Interfaces are designed to support dynamic method resolution at run time.
Interfaces do not have constructor.
 

why are interfaces used?

  • to achieve total abstraction.
  • to achieve multiple inheritance.
  • to achieve loose coupling.
 
interface Company { final long ANNUAL_BUDGET = 100000000; boolean grow(); }
 

Real-world example of interface

Interface BaseEngine
interface BaseEngine { // all are the abstract methods by default. void changeGear(int a); void accelerate(int a); void slowDown(int a); }
ElectricEngine Class that is implementing Interface
class ElectricEngine implements BaseEngine{ int speed; int gear; // to change gear @Override public void changeGear(int newGear){ gear = newGear; } // to increase speed @Override public void accelerate(int increment){ speed = speed + increment; } // to decrease speed @Override public void slowDown(int decrement){ speed = speed - decrement; } public void printStates() { System.out.println("speed: " + speed + " gear: " + gear); } }
PetrolEngine Class that is implementing Interface
class PetrolEngine implements Vehicle { int speed; int gear; // to change gear @Override public void changeGear(int newGear){ gear = newGear; } // to increase speed @Override public void speedUp(int increment){ speed = speed + increment; } // to decrease speed @Override public void applyBrakes(int decrement){ speed = speed - decrement; } public void printStates() { System.out.println("speed: " + speed + " gear: " + gear); } }
 
class Car implements Engine { Engine engine; Car(Engine engine){ this.engine = engine } void switchEngine(Engine engine) { if(this.engine instanceof PetrolEngine){ this.engine = new ElectricEngine(); } else { this.engine = new PetrolEngine(); } } }

caution when using interfaces

Dynamic lookup of a method at run time incurs a significant overhead, so it should be avoided in performance critical code
 

Nested Interfaces

An interface can be declared a member of a class or another interface.
A nested interface can be declared as public, private, or protected. But a top-level interface is always public
// This class contains a member interface. class A { // this is a nested interface public interface NestedIF { boolean isNotNegative(int x); } } // B implements the nested interface. class B implements A.NestedIF { public boolean isNotNegative(int x) { return x < 0 ? false: true; } } class NestedIFDemo { public static void main(String args[]) { // use a nested interface reference A.NestedIF ref = new B(); if(ref.isNotNegative(10)) System.out.println("10 is not negative"); if(ref.isNotNegative(-12)) System.out.println("this won't be displayed"); } }

References: