Javaを09(インタフェース、継承、インタフェース、継承)に設定


インタフェース(残り)


Interface variable


変数はすべて自動的にpublic static final変数になります.したがって,これらの変数は利用可能であり,クラスの実値に関係なくfinalは値を変更しないため定数のように使用できると考えられる.
interface Motion{
	int NORTH = 1;
    int EAST = 2;
    int SOUTH = 3;
    int WEST = 4;
    
    void move(int direction);
    int getX();
    int getY();

}

class TwoDMotion implements Motion {
	private int posX, posY;
	public TwoDMotion() { posX = 0; posY = 0; }
    
    // 여기와 같이 interface의 변수들이 상수처럼 사용되고 있다.
	public void move(int direction) {
		if(direction == NORTH) posY--;
		else if(direction == SOUTH) posY++;
		else if(direction == EAST) posX++;
		else if(direction == WEST) posX--;
	}
    
	public int getX() { return posX; }
	public int getY() { return posY; }
}

Interface method


現在、interfaceの関数はabstract関数と呼ばれていますが、javaのバージョンが8/9になるにつれて、他の形式の方法が現れました.
  • static method (java 8)
  • default method (java 8)
  • private method (java 9)
    (今java 14です.)
  • static method
    この方法は内包を話している.
    今回はクラスオブジェクトを作成する方法のファクトリメソッドについてお話しします.
  • interface IntSequence{
    
    	// 이러한 형태의 메소드를 factory method라고 부른다.
    	static IntSequence digitsOf(int n){
    		return new DigitSequence(n);
    	}
        boolean hasNext();
        int next();
    }
    それを使うために、
    IntSequence digits = IntSequence.digitsOf(1729);
    上記のようにclassメソッドを呼び出すことで使用できます.
  • Default method
    インタフェースの内部では,メソッドにはdefault宣言があり,実装もある.したがって、クラスがインタフェースを実装する場合、サブクラスがインタフェースのdefault methodを宣言しない場合、default method機能のextendsを使用してクラスを継承し、継承クラスと同様の形式の結果を生成します.
  • 目的:コード重複を減らす
    たとえば、既存のクラスをインタフェースとして受信する場合は、毎回新しい関数を定義する必要があります.そのため、かなり面倒な状況になるのは避けられない.
    intercface IntSequence{
    	default boolean hasNext() {return true;}
        int next();
    }
    
    //아래와 같이 클래스는 implements 하였지만 
    //hasNext를 새롭게 정의하지 않았다.
    class SquareSequence implements IntSequence{
    	private int i;
        public int next(){
    		i++;
            return i * i;
        }
    }
    しかし、問題も発生します.2つのクラスのimplementsを受信すると、各クラスに同じ名前のメソッドがあり、問題が発生する可能性があります.
    interface Person {
    	String getName();
    	default int getId() { return 0; } 
        // Error: duplicate 		
        // default methods with the same type of parameters
    }
    
    interface Identified {
    	default int getId() { return 1; } 
        // Error: duplicate 
        // default methods with the same type of parameters
    }
    
    class Employee implements Person, Identified {
    	private String name;
    	public Employee(String name) { this.name = name; }
    	public String getName() { return this.name; }
    }
    
    public class Lecture {
    	public static void main(String[] args) {
    		Employee m = new Employee("Peter");
            //바로 이부분에서 문제가 생길 수 있다.
    		System.out.println(m.getId());
    	}
    }
  • ソリューション
  • の2つのクラスの1つがdefaultでない場合、問題は発生しません.
  • またはサブクラスで関数を個別に定義した場合、問題は発生しません.
  • の2つのクラスの1つのdefaultメソッドのパラメータまたは戻り値が異なる場合、問題は発生しません.
  • private methods
    privateメソッドとは、インタフェース内でのみ呼び出されるメソッドです.
    メソッド4はprivateとして宣言され、以下に示す.
    また,ここでは,既存の静的メソッドは静的メソッドの内部でのみ呼び出され,静的メソッドはdefaultメソッドでも呼び出されることが分かる.すなわち,既存の静的との区別は存在しないがprivateを宣言することによって外部から静的メソッドへのアクセスが阻止される.
  • interface CustomInterface {
    	public abstract void method1();
    	public default void method2() {
    		// private method를 당연하듯이 사용한다.
        		method4(); 
        		// 또한 여기와 같이 static method로 
            	// 정의된 method5가 default method에서 
            	// 호출 된 것을 확인할 수 있다.
    		method5(); 
    		System.out.println("default method");
    	}
    	public static void method3() {
    		method5(); 
        	//static method inside other static method
    		System.out.println("static method");
    	}
    	//method4 private 선언 : 함수의 구현도 해주었다.
    	private void method4() {
    		System.out.println("private method");
    	}
    	//private static method가 선언되어 있다.
    	private static void method5() {
    		System.out.println("private static method");
    	}
    }
    ただし、メソッド4は、インタフェースを継承する他のクラスでは使用できません.
    public class Lecture implements CustomInterface {
    	public void method1() {
    		System.out.println("abstract method");
    	}
        //현재 여기에서는 method4의 호출을 하지 않았으나 사용이 불가능하다.
    	public static void main(String[] args){
    		CustomInterface instance = new Lecture();
    		instance.method1();
    		instance.method2();
    		CustomInterface.method3();
    	}
    }

    このときいくつかのルール(試験)があります

  • privateメソッドは抽象的ではありません.=>必ず内部を体現しなければならない.
  • privateメソッドは、定義されたインタフェース内でのみ使用できます.
  • プライベート静的方法は、他の静的または非静的方法から呼び出すことができる.(これは既存の静的メソッドと変わらないが、外部からの静的メソッドへのアクセスを阻止する.)
  • プライベート静的方法内部では、他の非静的方法を導入することはできない.(private staticは自由に使えます!でも入らないでください-違いはありません.)
  • 継承


    2つのクラス間の関係.
    関係をsuperclassとsubclassに分けます.

    Extending a class

  • コードの重複性を低減します.
  • class Employee{
    	private String name;
        private int salary;
        public Employee(){
    		this.name = "NoName";
            this.salary = 0;
    	}
    	public String getName() {return this.name;}
        public void setName(String name) {this.name = name;}
        public int getSalary() {return this.salary;}
        public void setSalary(int salary) {this.salary = salary;}
    }
    extendsを使用してクラス名を追加すればいいです.
    class Manager extends Employee{
    	private int bonus;
        public void setBonus(int bonus) {this.bonus = bonus;}
    }
    これにより、Manager classは、Employee classでpublicとして宣言された関数と変数を使用して、新しい関数と変数を定義できます.

    Super class vs Sub class


    Managerはサブクラスです.
    Employeeは一流です.
    public static void main(String[] args){
    	Manager m = new Manager();
        System.out.println(m.getName() + " " + m.getSalary());
    }

    Method overriding


    今、クラスを継承したら、同名の新しい関数を定義したくないのでしょうか???だから提案した概念は誇張だ.overridingとはsuperclassでサブクラスの関数を再定義して使用することです.
  • 親の機能
  • を使用
    superclass関数を同時に使用する場合は、superキーワードを使用してsuperclass関数を呼び出すことができます.
    class Manager extends Employee{
    	private int bonus;
        public void setBonus(int bonus) {this.bonus = bonus;}
        //아래는 함수의 재정의 + superclass 함수의 사용을 보여준다.
        public int getSalary(){
    		return super.getSalary()+bonus;
    	}
    }
    ここでaccessmodifierの概念を考え直しましょう
    public>protected>なし>privateの順にアクセスできることを知っています.ここで、継承時に使用できる範囲は保護されています.
    class Manager extends Employee {
    	private int bonus;
    	public void setBonus(int bonus) { this.bonus = bonus; }
    	public int getSalary() {
    		return this.salary + bonus;
            // Error: salary is private in class Employee.
    	}
    }
    そのため、上記の超一流の給与を使うことは不可能だという誤った表現が発生します.
    また、継承されたクラスは、親クラスの作成者を同時に呼び出す必要があります.
  • ベーシック
    基本は同じ名前の関数で書きます.
  • class Employee {
    	private String name;
    	protected int salary;
    
    	public Employee() {
    		this.name = "NoName";
    		this.salary = 100000;
    	}
    	public String getName() {return this.name;}
    	public void setName(String name) {this.name = name;}
    	public int getSalary() {return this.salary;}
    	public void setSalary(int salary) {this.salary = salary;}
    }
    
    class Manager extends Employee{
    	private int bonus = 50000;
    	public void setBonus(int bonus) {this.bonus = bonus;}
    	public int getSalary() {
    		return super.getSalary()+bonus;
    	}
    }
  • パラメータが異なりoverridingとは認められません
    書き換え方法を考えてみましょう
    class Employee{
    	private String name;
        protected Employee supervisor;
        public Employee(){
    		this.name = "NoName";
    	}
        public boolean worksFor(Employee supervisor){
    		System.out.println("Employee.worksFor");
            return (this.supervisor == supervisor)
    	}
    }
    
    class Manager extends Employee{
    	public boolean worksFor(Manager supervisor){
    		System.out.println("Manager.worksFor");
            return (this.supervisor == supervisor)
    	}
    }
    パラメータが異なるため、マネージャのEmployee関数はハイパースレッドではなく、ハイパースレッドのみであり、他の関数が定義されています.
    だからこれらの問題を解決するために.
    class Manager extends Employee{
    	@Override
    	public boolean worksFor(Manager supervisor){
    		System.out.println("Manager.worksFor");
            return (this.supervisor == supervisor)
    	}
    }
    @Overrideキーワードを関数の上に書き込みます.これでエラーが発生します.この点から,これは問題のあるコードであることが分かった.
    したがって,誤りを防止するために,@Overrideというキーワードをできるだけ使うことが誤りを防止する最善の方法である.
  • レベル返却型はカバー率に影響しますか?
  • 正解はYES
    還付刑が違うと、過剰生活と認定されます.サーブのタイプだけが認められる.そうではありません.普通の資料型ではあり得ません.これは関数の終了時に影響を与えるので、最初はあまり重要ではありません.ただし、それでもできるだけ@Overrideを作成
    class Employee {
    	private String name;
    	protected Employee supervisor;
    	public Employee() {
    		this.name = "NoName";
    	}
    	public Employee getSupervisor() {
    		System.out.println("Employee");
    		return supervisor;
    	}
    }
    
    class Manager extends Employee {
    	@Override // this is ok!
    	public Manager getSupervisor() {
    		System.out.println("Manager");
    		return (Manager)supervisor;
    	}
    }
  • access修飾子は関数overridingとして認定されますか?
  • 正解はYES
    正確には,サブクラスの制限レベルがより高くなると問題が発生する.しかし、その役なら認められる.でも、プライベートでは無理です.

    過負荷承認範囲


  • access modifier
    承認X


  • もどりがた
    承認X


  • パラメータ
    承認O

  • @Override承認範囲

  • access modifier
    承認O(ただし、サブクラスはスーパークラスの制限以下である必要がある)
  • エラー正常

  • 一般資料型返却型
    承認X


  • クラスデータ戻りタイプ
    承認O


  • クラスパラメータ
    承認X