How is abstraction achieved through abstract classes and interfaces

Question from Data20#5839

How is abstraction achieved through abstract classes and interfaces?

I may have a misunderstanding somewhere, so I'll elaborate on where I'm at with the concept.

From my understanding: Abstraction is a concept of OOP that focuses on hiding implementation detail and showing only what is necessary. The functional detail

This is the example I see when I go with this definition:

public class Base {

    public int area(int length, int width){
        return length * width;
    }
}

public class Main {
   public static void main(String[] args) {
        Base r1 = new Base();

        System.out.println("The area of this rectangle is " + r1.area(5,6) + ".");
    }
}

When I called the area method in Base, I just wanted the area of a rectangle. I didn't need to know the actual formula for it, just the result of it.

Having said that, I feel that I'm off somewhere and am confused with how abstraction is achieved with Abstract classes and Interfaces.

Okay so first - abstraction is not a concept of OOP.

Your area method does abstract the actual mechanism of computation. i.e. you could rewrite it like this

public int area(int length, int width){
    if (width < 0) {
        return area(length, -1 * width) * -1;
    }
    else if (width == 0) {
        return 0;
    }
    else {
        return length + area(length, width - 1);
    }
}

and its contract to the rest of the code would remain the same.

What interfaces give you is a mechanism for polymorphism. For instance if I wrote code like this

public enum IntOrder {
    LessThan, EqualTo, GreaterThan;
}

public final class IntComparator {
    public IntOrder compare(int a, int b) {
        if (a < b) {
            return LessThan;
        }
        else if (a == b) {
            return EqualTo;
        }
        else {
            return GreaterThan
        }
    }
}

I've successfully abstracted the process of comparing two integers and if I wanted to write a sort function

public static int[] sort(int[] xs) {
    // somewhere i can call new IntComparator.compare(...); and use that for ordering
}

I could use that abstracted comparison behavior.

But if I wanted the sort function to "be abstracted" over how it compares these integers I could use an interface

public interface IntComparator {
    IntOrder compare(int a, int b);
}

...

public final class NormalIntComparator implements IntComparator {
    public IntOrder compare(int a, int b) {
        if (a < b) {
            return LessThan;
        }
        else if (a == b) {
            return EqualTo;
        }
        else {
            return GreaterThan
        }
    }
}

...

public static int[] sort(int[] xs, IntComparator comparator) {
    // somewhere i can call comparator.compare(...); and use that for ordering
}

And this would let me write many different implementations of comparing ints. For instance, maybe comparing them in reverse order and treat them "the same" in some other abstraction.

So polymorphism has utility in building abstractions and interfaces give you polymorphism.

Abstract classes give you polymorphism and code sharing, but their primary utility is code sharing.

You can still make abstractions and get polymorphism in non OOP languages your mechanisms for doing so will just be different.

I'm taking in what all you said. From the readings I've done, I've always thought that Abstraction was apart of OOP.

In your defense, a large part of why OOP and specifically Java is so omnipresent is heavy degrees of marketing and hype. A lot of what you read probably never stops to point out nuance since its all somewhat derived from marketing.


<- Index