抽象クラスとインタフェース


🔔 Goal

  • 簡単な文法と使い方の違いに焦点を当てない.
  • 抽象クラスとインタフェースの本当の違いを理解します.
  • 🌳 抽象クラス


    抽象クラスは普通のクラスと何の違いもありません.
    ただし、抽象メソッドを宣言することで、サブクラスで完了したクラスを継承するように導きます.
    従って未完成の設計図としても表現される.
    継承に使用されるクラスなので、オブジェクトを個別に作成することはできません.
    abstract class 클래스이름 {
        ...
        public abstract void 메서드이름();
    }

    🌳 インタフェース


    抽象クラスが未完成の設計図である場合、インタフェースは基本設計図と呼ぶことができる.
    インタフェースは抽象クラスのように,他のクラスの作成を支援することを目的として記述することもでき,クラスとは異なるマルチステート(実装)を実現することができる.
    interface 인터페이스이름 {
        public static final 상수이름 =;
        public abstract void 메서드이름();
    }

    🌳 抽象クラスとインタフェースの違い


    抽象クラスとインタフェースの共通点は抽象メソッドを使用できることです.
    では、なぜ2種類に分けて使わなければならないのでしょうか.
    抽象クラスとインタフェースの機能から見ると、抽象クラスはインタフェースの役割を果たすことができますが、なぜインタフェースが必要なのでしょうか.
    理論的な違いを除いて、2つに分けて使う最大の違いは使用用途だと思います.

    🍃 使用目的の違い


    抽象クラスはIS-A"~".
    インターフェイスはHAS-A"~"ができます
    このように区別する理由は多重継承の可能性によって用途が決まるようだ.
    Javaのプロパティのため、継承できるクラスは1つだけです.
    すなわち,抽象クラス継承によりそのクラスの区分を解決し,インタフェースにより実現可能な機能を実現する.

    🍃 汎用機能を使用するかどうか


    すべてのクラスがインタフェースを使用して基本フレームワークを構築する場合、共通の機能はすべてのクラスで上書きして再定義する必要があります.
    このような共通の機能が必要な場合は、抽象クラスを使用して汎用メソッドを作成し、サブクラスで使用できます.
    では抽象クラスだけ使えばいいのではないでしょうか.
    前述したように、Javaは1つのクラスしか継承できません.
    各抽象クラスに共通の機能が必要な場合は?この機能をインタフェースに記述すると、より便利になります.

    🍃 抽象クラスインタフェースの例(生命体)



    人と動物は生命体を継承し、各生命体は人と動物を区別して継承する.
    インタフェースの形でそれぞれ実現可能な機能を実現した.
    public abstract class Creature {
        private int x;
        private int y;
        private int age;
        
        public Creature(int x, int y, int age) {
            this.age = age;
            this.x = x;
            this.y = y;
        }
        
        public void age() {
            age++;
        }
        
        public void move(int xDistance) {
            x += xDistance;
        }
        
        public int getX() {
            return x;
        }
        public void setX(int x) {
            this.x = x;
        }
        public int getY() {
            return y;
        }
        public void setY(int y) {
            this.y = y;
        }
        
        public abstract void attack();
        public abstract void printInfo();
    }
    基本的に生命体が持つ要素であり,位置x,y,年齢がある.
    また,年を取るとx座標上を移動できる部分が共通の機能であるため,サブクラスから継承するための従来の方法として実現される.
    抽象的な方法は攻撃機能と出力情報機能を発表した.
    これはすべての生命体に必要な機能ですが、各生命体は異なる機能を実現する必要があるため、この2つの方法は抽象的な方法として宣言され、サブクラスで処理されます.
    Animal抽象クラス
    public abstract class Animal extends Creature{
        
        public Animal(int x, int y, int age) {
            super(x, y, age);
        }
        
        @Override
        public void attack() {
            System.out.println("이빨을 사용하여 공격!!");
        }
    }
    動物類は生命体であるためCreature抽象類を継承している.
    動物は歯を使って攻撃するので、抽象的な方法で攻撃方法を誇張した.
    printInfo法も抽象的な方法ですが、なぜ動物類にはないのでしょうか.
    この理由は機能が1つ増えたからです.生命体類も動物類も抽象類です.
    すなわち,親に宣言された抽象的な方法を,後で動物類を継承するクラスに委任する.
    ヒューマン抽象クラス
    public abstract class Human extends Creature implements Talkable{
        public Human(int x, int y, int age) {
            super(x, y, age);
        }
        
        @Override
        public void attack() {
            System.out.println("도구를 사용!!");
        }
        
        @Override
        public void talk() {
            System.out.println("사람은 말을 할 수 있다.");
        }
    }
    人間類も同様であり,攻撃抽象法は実現され,printInfo抽象法は下に委任されている.
    ヒト類は動物類と異なり,Talkableインタフェースを実現している.
    Talkableインタフェースではtalk法が抽象法として存在することが予想される.
    Talkableインタフェース
    public interface Talkable {
        abstract void talk();
    }
    Talkableインタフェースでは,大きな問題はなく,抽象的な方法のみを宣言した.
    作成したインタフェースのネーミングルールを見れば分かるように、~ableで終わるインタフェースがたくさんあります.
    すべてのインタフェースがそうであるわけではありませんが、「~」クラスを示すために使用されます.
    ex) Parsable, Comparable...
    Flyableインタフェース
    public interface Flyable {
        void fly(int yDistance);
        void flyMove(int xDistance, int yDistance);
    }
    以下に,新しい種類の動物類に現れるFlyableインタフェースを示す.
    他の動物とは異なり、y行を上に進む方法が発表された.
    Pigeon一般クラス
    public class Pigeon extends Animal implements Flyable{
        public Pigeon(int x, int y, int age) {
            super(x, y, age);
        }
        
        @Override
        public void fly(int yDistance) {
            setY(getY() + yDistance);
        }
        
        @Override
        public void flyMove(int xDistance, int yDistance) {
            setY(getY() + yDistance);
            setX(getX() + xDistance);
        }
        
        @Override
        public void printInfo() {
            System.out.println("Pigeon -> " + toString());
        }
    }
    ハト類は普通類です.
    動物類の飛翔を継承できる動物であるため、Flyableインターフェースを実現し、対応する方法を実現した.
    printInfoメソッドから見ると,以前はCreatureクラスの抽象メソッドを上書きしていた.
    伸縮性コネクタ
    public interface Swimable {
        void swimDown(int yDistance);
    }
    このインタフェースは、異なる点で2です.これは、共通の機能を使用するかどうかに関するインタフェースです.
    私たちは亀とケビンというクラスを書きます.亀は動物で、ケビンは人間です.
    しかし、二つの生命体は泳ぐことができます.この場合、生命体クラスにswinDown抽象メソッドを作成するべきですか?それとも動物と人間のクラスに抽象的な方法を作成すべきですか?
    しかし動物や人の中には泳げない人もいるかもしれません.言い換えれば、すべての生命体が泳げるわけではないし、動物や人にも泳げない相手がいるかもしれない.
    では、抽象的な方法を作るのは正しいことではないでしょうか.
    このような場合はインタフェースでDaと宣言し,それをそれぞれ泳ぐことができるクラスに反映すると,可読性が良いだけでなく,メンテナンスにも優れている.
    Turtle一般クラス
    public class Turtle extends Animal implements Swimable{
        public Turtle(int x, int y, int age) {
            super(x, y, age);
        }
        
        @Override
        public void swimDown(int yDistance) {
            setY(getY() - yDistance);
        }
        
        @Override
        public void printInfo() {
            System.out.println("Turtle -> " + toString());
        }
    }
    Kevin一般クラス
    public class Kevin extends Human implements Programmer, Swimable{
        public Kevin(int x, int y, int age) {
            super(x, y, age);
        }
        
        @Override
        public void coding() {
            System.out.println("Hello World!");
        }
        
        @Override
        public void swimDown(int yDistance) {
            setY(getY() - yDistance);
            if(getY() < -10) {
                System.out.println("너무 깊이 들어가면 죽을수도 있어!!");
            }
        }
        
        @Override
        public void printInfo() {
            System.out.println("Kevin -> " + toString());
        }
    }
    カメ類では、下に泳ぐ機能を再定義することができ、Kevin類でも上書きして再定義することができます.
    Kevinの場合、y値が-10以下に下がると死ぬ可能性があることを知らせる機能として再定義します.
    この点では、抽象クラスではなくインタフェースを使用するメリットを徐々に理解してみましょう.
    もう一つのインタフェースの利点は多重口賢で,Kevinは水泳も符号化もできる.したがって,ProgrammerとSwibleインタフェースを実装し,必要なメソッドを再定義することができる.
    Programmerインタフェース
    public interface Programmer {
        void coding();
    }

    🌳 整理する


  • 抽象クラスの使用方法:継承関係を上に移動すると、同じ親クラスが継承され、完全に同じ機能が必要になります.
    (ex. attack, printInfo)

  • インタフェースの使用方法:継承関係でアップグレードする場合、他の親と同じ機能を継承する必要がある場合.
    (ex. Swimable)
  • 🌳 Reference

  • MyZamongのブログ
    これは私が見た抽象クラスとインタフェースの違いに関する文章の中で一番いいです!