ในครั้งนี้เราจะลองนำ interface มาใช้งานในอีกรูปแบบหนึ่ง ที่ไม่ใช่เป็นรูปแบบของ Listener

โดยตัวอย่างของเราจะมี Interface OperatingSystem

public interface OperatingSystem {

   String getOSVersion();

}

ที่มี method getOSVersion และเราจะมี Class OpenBSD และ FreeBSD ที่จะ implement interface นี้

public class FreeBSD implements OperatingSystem{

    public String getOSVersion() {
        return “FreeBSD”;
    }

}

public class OpenBSD implements OperatingSystem {

    public String getOSVersion() {
        return “OpenBSD”;
    }

}

แล้วเราจะมีคลาส MyComputer ที่จะรับคลาสใดๆ ที่ implement interface OperatingSystem

public class MyComputer {

    OperatingSystem os;
   

    public MyComputer(OperatingSystem os) {
        this.os = os;
    }
    public String getOSVersion(){
    return os.getOSVersion();
    }

นั่นคือคลาส MyComputer จะใช้ method getOSVersion จาก inteface OperatingSystem ในการ return ชื่อของ OS ออกมา ไม่ว่าจะเป็นคลาส OpenBSD หรือ FreeBSD ก็สามารถเรียกใช้งาน method นี้ได้จากคลาสเหล่านั้นทันที

MyComputer desktop = new MyComputer(new FreeBSD());
MyComputer notebook = new MyComputer(new OpenBSD());
System.out.println(desktop.getOSVersion());
System.out.println(notebook.getOSVersion());

ผลลัพธ์

FreeBSD

OpenBSD

ถ้าหากไม่มี interface เราก็คงจะต้องยุบคลาส openbsd และ freebsd เข้าไว้ด้วย แล้วไปกำหนด ว่าจะเป็น openbsd หรือ freebsd ตอนสร้างคลาส นั้นอีกทีหนึ่ง ซึ่งมีความยืดหยุ่นน้อยกว่าการทำคลาสแยกในลักษณะนี้

ทีนี้ก็จะมีคำถามว่าแล้วมันต่างกับการใช้งาน Abstract Class อย่างไร

Abstract class นั้นเป็นคลาส ที่เหมือนกับคลาสธรรมดาทั่วๆไป สามารถกำหนดค่า สร้างตัวแปรต่างๆ ได้ มี method ที่สามารถมี statement อยู่ภายในได้ หรือจะบังคับให้ implement method เหมือนกับ  interface ก็ได้ ทำให้ abstract class นั้นหมาะสมสำหรับการเป็น แม่แบบในการสร้างคลาสที่เกี่ยวข้องกัน ลองดูตัวอย่างการ implement ตัวอย่างข้างต้นในรูปแบบของ abstract class โดยเราจะกำหนดตัวแปรที่ชื่อว่า version คอยเก็บชื่อของ OS และตัวแปร stdPrice ที่จะเก็บราคามาตราฐานโดยตั้งต้นไว้ที่ 100 รวมทั้งเรามีการ implement method getOSVersion ไว้เรียบร้อยแล้ว แต่จะทำการบังคับให้ class ที่จะ extends abstract class นี้ต้องทำการ implement method calculatePrice ด้วย

abstract class OperatingSystem {

    String version;
    double stdPrice = 100;

    String getOSVersion() {
        return version;
    }

    abstract double calculatePrice();
}

เมื่อเรามาดูคลาสที่ทำการ extends abstract class ก็จะเห็นว่า คลาสเหล่านี้ไม่จำเป็นต้องมี method getOSVersion อีกต่อไป เหลือเพียงแต่การเซทค่าให้ตัวแปร version และทำการ implement method calculatePrice เท่านั้น

public class FreeBSD extends OperatingSystem {

    public FreeBSD() {
        version = “FreeBSD”;
    }

    @Override
    double calculatePrice() {
        return stdPrice*1.7;
    }
}

public class OpenBSD extends OperatingSystem {

    public OpenBSD() {
        version = “OpenBSD”;
    }

    @Override
    double calculatePrice() {
        return stdPrice*1.5;
    }
}

จะเห็นได้ว่าการใช้ abstract class ช่วยลด code ซ้ำซ้อนที่อาจจะเกิดขึ้นได้

แล้วเมื่อไหร่ถึงจะใช้ interface หรือ abstract class

interface นั้นเหมาะสำหรับให้ class ที่ไม่มีความเกี่ยวข้องกันเลย เรียกใช้ แต่ abstract นั้นเหมาะสำหรับ class ที่มีความเกี่ยวข้องกับ abstract แล้วทำให้เราสามารถใช้ feature ของ abstract class ได้