オブジェクト向けプログラミング-インタフェース


インタフェース


抽象クラスですでもちょっと違うインタフェースInterfaceは抽象メソッドを有するが、抽象度が高いため、抽象クラスとは異なり、具体化された従来のメソッドまたはメンバー変数をメンバーとすることはできない.メンバーには抽象的なメソッドと定数しかありません.他の要素は許可されません.
インタフェースを作成するのは、クラスを作成するのと同じです.classではなくinterfaceを使用する必要があります.またアクセス制御者としてはpublicまたはdefaultしか使用できない.
以下の制限事項もあります.
  • すべてのメンバー変数はpublic static finalである必要があります.
  • は省略できます.
  • すべての方法はpublic abstractでなければならず、省略することができる.
    (クラスメソッドとエラーメソッドを除く)
  • interface 인터페이스이름{
    	public static final 타입 변수 =;
        public 타입 변수 =; // 위와 동일
        public abstract 메서드이름(매개변수);
        메서드이름(매개변수);	// 위와 동일
    }
    本来インタフェースのすべてのメソッドは抽象メソッドJDK 1であるべきである.8に移動すると、インタフェースに静的メソッドとエラーメソッドを追加できます.
    interface Impl{
        static void FUNC() {}				// static 메서드
        default void func() { 				// default 메서드,
        									// 선언 안되면 얘를 실행해요. 접근 제어자는 public이에요
        	System.out.println("Impl");
        }
    }
    
    class A implements Impl{
        @Override
        public void func() {				// 물론 상속도 되요
        	System.out.println("A");
        }
    }
    ここで、デフォルトの方法はインタフェースを変更するのに役立ちます.デフォルトメソッドは抽象メソッドの基本的な実装を提供します.したがって,インタフェースメソッドを追加しても,そのインタフェースを継承するすべてのクラスを見つけることができ,これらのクラスを巡る煩わしさを改善することができる.以前から悩んでいた問題はJDK開発者たちの悩みを経て改善された結果でよい
    もちろん、追加すると、既存のメソッドの名前が変更され、競合するのは当然です.この問題を解決するルールは以下の通りです.
    1.複数のインタフェースのデフォルトメソッド間の競合
    実装インタフェースのクラスでデフォルトメソッドを上書きする
    2.デバッガメソッドと親メソッドの競合
    祖先クラスを継承する方法、デフォルトの方法を無視する方法
    interface a {
        default void func() {
            System.out.println("a");
        }
    }
    
    interface b {
        default void func() {
            System.out.println("b");
        }
    }
    
    // 다중 상속으로 메서드 중복이어도 오버라이딩하면 그만!
    class B implements a, b{
    	@Override 
        public void func() {
    
        }
    }

    JDK1.9以降はプライベートメソッドを使用できます


    JDK1.9に入るとprivateの方法が使用できます以下の特性を有する.
  • メソッド体があり、抽象的な
  • ではありません.
  • は、静的であっても非静的であってもよい
  • である.
  • 実装クラスおよびインタフェースは
  • を継承しない.
  • インタフェースは、他の方法
  • を呼び出すことができる.
    出典:https://flyburi.com/605[飛べ]
    たとえば、既存のprivateは使用できないので、エラーメソッドでのみ使用されるロジックを1つのロジックに配置する必要があります.異なる方法で実装すると、継承されたクラスが誤って使用されるためです.しかし、privateが許可された場合、きれいでアクセス制御領域を決定できるコードが完成した.
    JDK1.9点
    public interface VeryImportantInterface {
    	// 기존
    	default void coreFunc() {
        	// ㅁ애애애애우 중요하면서 만 줄이 넘어가는 코드야
            // 여기 로직들은 다 건들면 안돼
    	}
        // 개선
        default void coreFunc() {
        	// 너무 기니까 관리하기 힘들어... 나눠야지
        	coreFuncLevel1();
        	coreFuncLevel2();
        }
        // 앗! 근데 default다 보니까 상속하는 애들이 잘못 사용할 수도 있을텐데...
        // Level1의 로직을 오버라이딩해서 바꿨어
        // 상속한 애가 Level2만 필요하다고 써버렸어... 이러면 터질텐데 ㅠ
        default void coreFuncLevel1();
        default void coreFuncLevel2();
    }
    JDK1.9後
    public interface VeryImportantInterface {
    	// 기존
    	default void coreFunc() {
        	// ㅁ애애애애우 중요하면서 만 줄이 넘어가는 코드야
            // 여기 로직들은 다 건들면 안돼
    	}
        // 개선
        default void coreFunc() {
        	// 너무 기니까 관리하기 힘들어... 나눠야지
        	coreFuncLevel1();
        	coreFuncLevel2();
        }
        
        // 헤헤 이러면 아무도 접근 못해 오직 인터페이스만 할 수 있어
        // 이건 abstract가 아니라서 오버라이딩도 불가능해!
       	private void coreFuncLevel1() {
        	// 매우 중요한 코드 1단계
    	}
        private void coreFuncLevel2() {
        	// 매우 중요한 코드 2단계
    	}
    }

    インタフェースの継承


    インタフェースはインタフェースからのみ継承できます.クラスとは異なり、複数のインタフェース、すなわち複数のインタフェースから継承できます.
    interface Movable { void move(int x, int y); }
    interface Attackable { void attack(); }
    interface Fightable extends Movable, Attackable {
    	// 굳이 선언 안해도 move()와 attack()이 있어요
    }
    このように、Fightableインタフェースは、MovableおよびAttackableの抽象的な方法をメンバーに持たせることができる.
    あとインタフェースさえあれば何もできないでしょう?もちろんクラスの正式な具体化に継承しますimplementsキーワードで継承できます.もちろん,クラスはインタフェースに限られ,多重継承が可能である.
    class User extends Person implements Movable, Attackable {
    	// 인터페이스 추상 메서드 구현
    }
    // 위랑 같아요. Fightable은 두 인터페이스를 상속했으니까요
    class User extends Person implements Fightable {
    	// 인터페이스 추상 메서드 구현
    }
    
    // 되긴 해요. 다만 TMI라고 경고 메시지 떠요.
    class User extends Person implements Fightable {
    	// 인터페이스 추상 메서드 구현
    }

    インタフェースマルチ継承


    マルチ継承問題では、2人の親から受け継いだ方法の名前が同じであれば、曖昧性が生じ、誤りを招く.したがってJavaではクラス間の多重継承は許可されません.しかし、インタフェースはそれに取って代わることができます.しかし、これでは「多重継承を阻止する意味はないだろう」.そう思う
    インタフェースは多重継承のみ可能であるが,多重継承を実現する場合はほとんどない.抽象的な方法を宣言することで設計の完成度を高めることを目的としているからです.
    しかし、これは多重継承の利点を利用できないという意味ではない.例を挙げて説明しよう
    interface VeryImportantable {
    	default void func() {
        	// 매ㅇ애ㅐㅔ애애애우 중요하면서 만줄짜리 코드
    	}
    }
    interface VeeeryImportantable {
    	default void func() {
        	// 매ㅇ애ㅐㅔ애애애애애애애우 중요하면서 만줄짜리 코드
    	}
    }
    このように重要であるため,インタフェース上で誤った方法で実現した.しかし、この2つのインタフェースのレベルを使う必要があります.
    class App implements VeryImportantable, VeeeryImportantable {
    	
        public void func() {
        	// 오버라이딩은 했지만...어떤 코드를 가져와야 하지?
        }
    }
    このように文法的には問題ありませんが、必要に応じてVeryを書く必要がある場合もあれば、Veeryを書く必要がある場合もあります.もちろんその通りにすればいいのですが、これは効率的ではありません.誤った方法がspecによって論理を変更した場合、それを使用する子供もすべて適用すべきではないでしょうか.そのレベルが10個あるとしたら….
    従って、2つのインタフェースのうち比重の高い1つをクラスに含め、もう1つをクラスに含めてメンバーとして扱うことで、メンテナンスの観点から見ても、後続の修正を容易に行うことができる.
    class App implements VeeeryImportantable {
    	VeryImportantable i = new AppImpl();
        
        // 인터페이스 안에 있었던 추상 메서드들
    	public void exec() {
    		i.exec();
        }
        // 인터페이스 안에 있었던 추상 메서드들
    	public void exec2() {
    		i.exec2();
        }
        ...
    }
    
    class AppImpl implements VeryImportantable {
    
        // 인터페이스 안에 있었던 추상 메서드들
    	public void exec() {
        }
        // 인터페이스 안에 있었던 추상 메서드들
    	public void exec2() {
        }
        ...
    }
    このように多重継承を利用して,後で修正しやすいコードを記述することも可能である.

    かいめんたいけいせい


    たけいせいの概念を使用して、サブクラスのインスタンスを親参照変数として参照できます.
    interface a {}
    class A implement a {}
    
    a aInst = new A();		// Up-casting
    A aInst2 = (a)aInst;	// Down-casting
    既存のクラス間で多く形成されているルールと同じです(詳細はリンクハハを参照).

    リファレンス


    Berryが飛び上がったブログ
    baeldung - java interface private method