15日間の多形性、抽象クラス、インタフェース


タイプ変換が多すぎます


(1)多形性


-同じタイプで実行結果が異なるオブジェクトの置換
1)親タイプには、すべての子を含めることができます.
(サブタイプが親に自動的に変換されます)
2)効果:オブジェクトを部品化できる

(2)自動タイプ変換(Promotion)


-プログラム実行中に自動タイプ変換が発生
-継承レイヤの親を自動的に変換できます(親でなくても).
(変換後は親メンバーのみアクセス可能)

(3)場の多形性


-マルチフォーム化を実現するための技術的アプローチ
1)親タイプへの自動変換(多形1)
2)再定義の方法(オーバーラップ)(多形性2)
---------------------부모 클래스 형성 ------------------------
package polymorphismex;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Animal01 {

	void sound() { //자식객체에 물려줄 인스턴스 메소드 
		System.out.println("Animal::sound() invoked.");
	}//sound 
	
	
}//end class
---------------------자식 클래스 형성 ------------------------
package polymorphismex;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Dog02 extends Animal01 {
	
	
	
	@Override
	void sound() {
		System.out.println("Dog::sound() invoked.");

	}//sound
	
	void dogMethod() {
		System.out.println("bow - wow");
	}// dogMethod
	
	
}//end class
---------------------부모 클래스2 형성 ------------------------
package polymorphismex;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Cat03 extends Animal01 {
	
	
	
	@Override
	void sound() {
		System.out.println("Cat::sound() invoked.");

	}//sound
	
	void catMethod() {
		System.out.println("CCCCCCAAAAAAAAKKKKKKK");
	}// dogMethod

	
	
}//end class
-----------------------------다형성 실행---------------------------
package polymorphismex;

public class PPP04 {

	public static void main(String[] args) {
		
		// 1. 다형성-1: 부모타입의 참조변수에 모든 자식객체 대입이 가능
		Animal01 animal = new Dog02(); // OK
		System.out.println("1)animal: " + animal);
		
		//2. 다형성-2: 부모타입의 참조변수의 메소드를 호출할 때, 
		// 			   무조건 자식객체가 재정의한 메소드가 호출된다. 
//		animal.dogMethod(); xx
		animal.sound();
		
//		----
		animal = new Cat03(); // 클래스 본판 변경!
		System.out.println("2)animal: " + animal);
	
//		animal.catMethod(); xx
		animal.sound();
		
	}//main

}//end class

(4)パラメータの多形性


-パラメータがクラスタイプの場合
1)クラス内のオブジェクトを原則またはサブオブジェクトに置き換えることを許可する
(自動タイプ変換)(パラメータの多形性)
---------------------------부모 클래스 형성-------------------------
package polymorphismex02;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Vehicle {
	
	public void run() {
		
		System.out.println("Vehicle::run() invoked.");
	}//run
}// end class
---------------------------자식 클래스 형성-------------------------
package polymorphismex02;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Bus02 extends Vehicle{

	@Override
	public void run() {
			
		System.out.println("Bus::run() invoked.");
	}//run

	
}//end class
---------------------------자식 클래스 형성-------------------------
package polymorphismex02;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Taxi03 extends Vehicle{

	@Override
	public void run() {
			
		System.out.println("Taxi::run() invoked.");
	}//run

	
}//end class
---------------------------매개변수 다형성 실행-------------------------
package polymorphismex02;

public class DriverEx05 {

	public static void main(String[] args) {
		DriverEx05 dr = new DriverEx05();

		Bus02 bus = new Bus02(); 		 // 자식객체 생성
	    Taxi03 taxi = new Taxi03();		 // 자식객체 생성
	    
	    dr.drive(bus);				// 매개변수는 부모클래스 자식객체를 인자로 전달
	    dr.drive(taxi);  			// 매개변수는 부모클래스 자식객체를 인자로 전달
	}//main

	
	public void drive(Vehicle vehicle) {
		
		System.out.println("Driver::drive(vehicle) invoked.");
		
		vehicle.run();
		
	}// drive
	
	
	
}// end class

(5)強制型変換(Casting)


-親タイプを子タイプに変換
-条件
サブタイプを自動的に親タイプに変換し、サブタイプに再変換します.
-タイプ変換を強制する必要がある場合
1)子タイプを親タイプに自動的に変換
(親タイプで宣言されたフィールドとメソッドのみ使用可能)
2)サブタイプに宣言されたフィールドとメソッドを再使用する必要があります.
---------------------------자식 클래스 형성-------------------------
package ex_04_12.casting;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Child extends Parent{
	public String field2;
	

	public void method3() {
		System.out.println("parent::method3 invoked.");
	}// me3
	
}// class end
---------------------------자식 클래스 2 형성-------------------------
package ex_04_12.casting;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Child2 extends Parent{
	public String field3;
	

	public void method4() {
		System.out.println("parent::method3 invoked.");
	}// me3
	
}// class end
---------------------------부모 클래스 형성-------------------------

package ex_04_12.casting;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Parent {
	public String field1;
	
	public void method1() {
		System.out.println("parent::method1 invoked.");
		
	}//me1
	public void method2() {
		System.out.println("parent::method2 invoked.");
	}// me2
	
}// class end
--------------------------- Casting-------------------------

package ex_04_12.casting;

public class ChildEx {

	public static void main(String[] args) {
		Parent parent = new Child();
		
		parent.field1 = "data1";
		parent.method1();
		parent.method2();
		
//		-----------
		
//		parent.field2 = "data2"; 에러 
//		parent.method3() ;    에러  
// 		이유: 부모클래스에는 해당 필드와 메소드가 없고 이를 참조타입으로 삼았기 때문에 안됌.
     		
//		-------
		
		// 자식객체 고유의 필드와 메소드를 사용해야 할 때에는 어떻게 합니까 ? 
		Child child =(Child) parent; // 다형성-1이 전제조건하에서 ,  자식객체를 빼낼 때 필요
		//단 child 1인지 2인지 3인지 자식이 무수히 많을 때 정확하지 않을 수도 있다. 
		
		
		child.field2 = "yyy";  //가능
		child.method3();  //
		
		
		
//		-------정확하지 않음에 검사해주는 instanceof를 사용한다. 
		if(parent instanceof Child) {
			Child child2  =  (Child) parent;
			
			child2.field2 = "yyy";  //가능
			child2.method3();  //가능
		}// if 
		// 이는 자바에 엄청나게 부담이 되기때문에 이를 해결하기위해 제네릭이 나옴
		
	}//main

}//end class

抽象クラス


(1)抽象クラス概念


  • エンティティ間の共通のプロパティの抽出

  • 抽象クラス
    1)エンティティクラスの共通フィールドとメソッド定義クラス
    2)抽象クラスがエンティティークラスの親ロール(排他オブジェクトX)である
  • (2)抽象クラスの用途


    -エンティティクラスを統合するための共通フィールドとメソッドの名前
    (1)エンティティークラスに複数の設計者がいる場合、
    (2)各エンティティークラスのフィールドとメソッドには異なる名前を付けることができる
    -エンティティークラスの作成に時間を節約
    (1)エンティティークラスが他のフィールドとメソッドのみを宣言する
    -エンティティークラス設計仕様の作成時
    (1)抽象クラスでエンティティクラスが持つべきフィールドとメソッドを事前定義する
    (2)実体クラスは無条件に抽象クラスを継承して作成される.

    (3)抽象クラス宣言(abstractキーワード)


    -New演算子を使用してオブジェクトを作成できません.継承のみでサブクラスを作成できます.

    (4)抽象メソッドとオーバーライド(再定義)


    -メソッド名は同じですが、実行内容がエンティティークラスと異なるメソッド
    -実装方法
    1)抽象クラスにのみメソッドを作成する宣言(抽象メソッド)
    2)エンティティークラスでメソッドの実行内容を作成する(overriding)
    ----------------------------추상클래스/메소드 선언 ---------------------------
    package ex_04_12.abstractex;
    
    public abstract class Animal { //객체를 직접 생성 불가 
    	public String kind;
    	
    	public void breathe() {
    		System.out.println("Animal::breathe() invoked.");
    	} // breathe
    	
    	//추상메소드란? 구현 block이 없이 메소드 선언부만 있는 경우를 의미 
    	public abstract void sound(); // 추상메서드 : 강제규격 (To 자식 재정의를...) 
    	
    }// end class
    ---------------------------오버라이딩 및 추상메서드 구현------------------------
    package ex_04_12.abstractex;
    
    public class Cat extends Animal { 
    	
    	
    	
    	public Cat() {
    		this.kind= "포유류";
    	}
    	
    	
    // 	무조건 재정의 하거나 자식도 abstract 지정해준다.
    	@Override
    	public void sound() {
    		System.out.println("야옹");
    	};  
    	
    }// end class
    

    インタフェース


    (1)コネクタ


    -開発コードとオブジェクト通信の接触点
    △コードを開発するには、インタフェースの方法を知るだけでよい.
    -インタフェースの役割
    開発コードをオブジェクトに依存させない->オブジェクトを置換する役割
    開発コードを変更しない場合、戻り値や実行が変化する可能性があります(多形性)

    (2)インタフェース宣言


    -インタフェース識別子慣例-classルールに従い、前にiを付けてインタフェースを区別する
    -インタフェースで宣言されたすべてのフィールドはpublic static finalです.
    -宣言時に初期値を指定します(静的ブロックは作成できません).
    -抽象メソッド宣言
    -エラーメソッド宣言
    -静的メソッド宣言
    --------------------------인터페이스 선언 ---------------------------
    package ex_04_12.interfaceex;
    
    //1. member : static final 상수 선언
    //2. member : 추상 메소드 선언
    //3. member : default 메소드 (기본 메소드 )
    //4. member : static 메소드 (공용 메소드 )
    public interface RemoteControl {
    	
    	public static final int MAX_VOLUME =10;
    	
    	int MIN_VOLUME =0;  // interface에서는 접근제한자 static final이 생략된다. 컴파일러가 자동으로 붙임
    	//하지만 이렇게 적어주지말자 오해한다. 
    	
    	//추상메서드 : 자식클래스에서 반드시 재정의시킬 강제 규격
    	void turnOn(); // public abstract가 생략 가능 하지만 생략하지마라!
    	public abstract void turnOff();
    	public abstract void setVolume(int volume);
    	
    	
    	//default 메소드 
    	public default void setMute(boolean mute) {
    		if(mute) {
    			System.out.println("무음을 처리합니다");
    		} else {
    			System.out.println("무음을 해제합니다");
    		}// if - else
    	}//setmute
    	
    	
    	
    	//정적 메소드 
    	public static void changeBattery() {
    		System.out.println("베터리를 교체합니다");
    		
    	}//changeBattery
    	
    	
    } // end interface
    

    (3)インタフェース実装


    -実装オブジェクトと実装クラス
    (インタフェース抽象メソッドを持つエンティティメソッドのオブジェクト=実装オブジェクト)
    (インプリメンテーションオブジェクトを作成するクラス=インプリメンテーションクラス)
    -クラス宣言の実装
    オブジェクトはインタフェースタイプ(implementsキーワード)として使用できます.
    -抽象メソッドのエンティティメソッドを作成します.
    メソッドの宣言部は完全に一致している必要があります.
    (一部のみ再定義されている場合は抽象クラスとして宣言されます)
    ------------------------------인터페이스 구현 클래스1 생성------------------------
    package ex_04_12.interfaceex;
    
    import lombok.NoArgsConstructor;
    
    //인터페이스: "부모", 구현클래스: "자식"
    @NoArgsConstructor
    public class Television implements RemoteControl{
    	//필드 
    	private int volume;
    	
    	
    	
    	@Override
    	public void turnOn() {
    		System.out.println("Audio를 켭니다.");
    	}; 
    	@Override
    	public  void turnOff() {
    		System.out.println("Audio를 끕니다.");
    	};
    	@Override
    	public  void setVolume(int volume) {
    		if(volume > RemoteControl.MAX_VOLUME) {
    			this.volume = RemoteControl.MIN_VOLUME;
    		} else if(volume < RemoteControl.MIN_VOLUME) {
    			this.volume = RemoteControl.MAX_VOLUME;
    		}else {
    			++volume;
    		}
    		
    	}// setVolume
    	
    }// end class
    
    ------------------------------인터페이스 구현 클래스2 생성------------------------
    package ex_04_12.interfaceex;
    
    import lombok.NoArgsConstructor;
    
    //인터페이스: "부모", 구현클래스: "자식"
    @NoArgsConstructor
    public class Audio implements RemoteControl{
    	//필드 
    	private int volume;
    	
    	
    	
    	@Override
    	public void turnOn() {
    		System.out.println("Audio를 켭니다.");
    	}; 
    	@Override
    	public  void turnOff() {
    		System.out.println("Audio를 끕니다.");
    	};
    	@Override
    	public  void setVolume(int volume) {
    		if(volume > RemoteControl.MAX_VOLUME) {
    			this.volume = RemoteControl.MIN_VOLUME;
    		} else if(volume < RemoteControl.MIN_VOLUME) {
    			this.volume = RemoteControl.MAX_VOLUME;
    		}else {
    			++volume;
    		}
    		
    	}// setVolume
    	
    }// end class

    (4)インタフェースの使用


    -抽象メソッド(実際に実装されたオブジェクトから)
    -エラーメソッド
    1)インタフェースのみ使用不可(インスタンスメソッド)
    2)全ての実施対象として使用されるデフォルトの方法
    -静的メソッド
    ダイレクトコール可能インタフェース(インタフェース名、メソッド名)
    --------------------------인터페이스 구현 클래스 사용 ----------------------------
    package ex_04_12.interfaceex;
    
    public class RemoteControlExample {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		RemoteControl rc;
    
    		rc = new Television(); //다형성 1
    		System.out.println("1. rc: " + rc);
    		
    		rc.turnOn();  // 다형성 2 
    		
    		rc = new Audio(); // 다형성 1 
    		System.out.println("1. rc: " + rc);
    		
    		rc.turnOn();
    
    	} // main
    
    } // end class

    (5)匿名実施対象


    -明示的なインプリメンテーションクラスの作成をスキップし、インプリメンテーションオブジェクトをすぐに取得する方法
    (名前のないインプリメンテーションクラスを宣言しながらオブジェクトを作成)
    (インタフェースのすべての抽象メソッドを再定義するエンティティメソッドが必要です)
    ------------------------------------익명 구현 객체 사용 ------------------------------
    package ex_04_12.interfaceex.noname;
    
    public class RemoteControlExample {
    
    	public static void main(String[] args) {
    		//익명 구현 rc에 저장
    		RemoteControl rc = new RemoteControl() {  
    			
    			String name = "kkk";
    			int age = 23; 
    			
    			
    			public void myMethod() {
    				System.out.println("Anonymous::myMethod() intvoked.");
    			} 
    			
    			
    			@Override
    			public void turnOn() {
    				System.out.println("Anonymous::turnOn() intvoked.");
    				System.out.println("\t + name:" + name);
    				
    			}//turnOn
    
    			@Override
    			public void turnOff() {
    				System.out.println("Anonymous::turnOff() intvoked.");
    				System.out.println("\t + name:" + age);
    			}//turnOff
    
    			@Override
    			public void setVolume(int volume) {
    				
    				System.out.println("Anonymous::setVolume() intvoked.");
    			}//setVolume
    			
    		};
    		
    		System.out.println(rc);
    		//다형성 -2 
    		rc.turnOn();
    		rc.setVolume(10);
    		rc.turnOff();
    		
    		//인터페이스를 통한 모든 구현객체의 기능 확장 
    		rc.setMute(true); //default 메소드 
    		RemoteControl.changeBattery(); // static 메소드
    	
    		
    		
    		
    //		----
    //		System.out.println(rc.name); 익명객체에서 구현된 오버라이딩 외의 멤버는 밖에서 사용 불가능
    //		System.out.println(rc.myMethod);
    		
    	}//main
    
    } // end class
    

    (6)マルチインタフェース実装クラス/インタフェース間の継承


    -マルチインタフェース実装クラス実装インタフェースのすべてのエンティティメソッド
    -サブインタフェース実装クラスは、以下のすべての抽象メソッドを再定義する必要があります.
    ---------------------------------인터페이스와 상속 동시 예제 -----------------------
    --------------------------------인터페이스 생성 -------------------------------
    package ex_04_12.multi;
    
    public interface Searchable {
    	
    	public abstract void search(String url);
    }// end interface
    -------------------------------클래스 생성--------------------------------
    package ex_04_12.multi;
    
    import ex_04_12.interfaceex.RemoteControl;
    
    public class SmartTelevision {
    
    	private int volume;
    	
    	public void turnOn() {
    		System.out.println("Audio를 켭니다.");
    	}; // t on
    	
    	public  void turnOff() {
    		System.out.println("Audio를 끕니다.");
    	};// t  off
    	public  void setVolume(int volume) {
    		if(volume > RemoteControl.MAX_VOLUME) {
    			this.volume = RemoteControl.MIN_VOLUME;
    		} else if(volume < RemoteControl.MIN_VOLUME) {
    			this.volume = RemoteControl.MAX_VOLUME;
    		}else {
    			++volume;
    		}
    		
    	}// setVolume
    
    }//class
    
    -----------인터페이스와 클래스 상속을 받는 클래스 생성----------------------
    package ex_04_12.multi;
    
    public class SmartTvEx extends SmartTelevision implements Searchable {
    
    	public static void main(String[] args) {
    		SmartTelevision tv = new SmartTvEx();
    		
    		tv.turnOn();
    //		tv.search("naver.com")  SmartTelevision에 메소드 정의 안되어있어서 안됌 
    		
    		
    		 Searchable Stv= (Searchable) tv;
    		 Stv.search("naver.com");
    //		 Stv.turnOn(); Searchable 에는 메소드 정의 안되어있어서 안됌 
    		 
    		 
    		 SmartTvEx smart = (SmartTvEx) Stv;
    		 smart.turnOn();
    		 smart.turnOff();
    		 smart.search("naver.com");
    		 
    	}//main
    
    	@Override
    	public void search(String url) {
    		System.out.println(url);
    	} // search
    
    }//class
    

    (7)拡張とデフォルトメソッドのインタフェース


    -デフォルトメソッドと拡張メソッドの使用
    -デフォルトのメソッドを持つインタフェースを継承します.
    -子インタフェースで親インタフェースを使用するポーリング方法
    1)デフォルトメソッドのみ継承
    2)エラーメソッドを再定義することで実行を変更する
    3)エラーメソッドを抽象メソッドとして再記述する
    -------------------------------------다중인터페이스와 인터페이스끼리의 상속 ----------------------------
    ------------------------부모 인터페이스 생성-------------------------
    package ex_04_12.interface_extends;
    
    public interface A {
    	public abstract void methodA();
    }
    
    ------------------------부모 인터페이스 생성-------------------------
    package ex_04_12.interface_extends;
    
    public interface B {
    	public abstract void methodB();
    	public default void methodBB() {
    	}
    }
    ----------------2명의 부모를 가진 자식 인터페이스 생성/ 디폴트 메소드 추상화--------------------
    package ex_04_12.interface_extends;
    
    public interface C extends A,B{ // 인터페이스의 상속은 여러개 가능 
    	public abstract void methodC();
    	
    //	@Override
    //	public abstract void methodBB(); //default 추상메서드로 재선언 
    }
    
    -------------------인터페이스들과 아무 관계 없는 인터페이스 ----------------
    package ex_04_12.interface_extends;
    
    public interface D {
    	public abstract void methodD();
    }
    
    ------------------------모두를 최종으로 다중 상속받는 클래스/디폴트 재선언----------------- 
    package ex_04_12.interface_extends;
    
    public class Cplaing implements C,D{
    
    	@Override
    	public void methodA() {
    		System.out.println("A구현");
    	}//A  주석처리하면 오류난다.
    
    	@Override
    	public void methodB() {
    		System.out.println("B구현");
    	}//B 주석처리하면 오류난다.  이유: C가 A,B를 상속했기 때문에 
    
    	@Override
    	public void methodC() {
    		System.out.println("C구현");
    	}//C
    	@Override
    	public void methodBB() {} // 상속받은 default 메소드 실행내용을 변경
    
    	@Override
    	public void methodD() {
    		
    	}
    }
    
    --------------------------최종 사용 예제 --------------------------------
    package ex_04_12.interface_extends;
    
    public class Example {
    	public static void main(String ... args) {
    		Cplaing ex = new Cplaing(); //구현 객체 생성.
    		
    		A a = ex ;			// 할아버지 인터페이스 
    		a.methodA();
    		
    		B b = ex;			// 할머니 인터페이스 
    		b.methodB();
    		
    		C c = ex;			// 부모 인터페이스 
    		c.methodC();
    		c.methodB();
    		c.methodA();
    		c.methodBB();
    		//구현 객체만 생성하면 조상의 조상 인터페이스까지 참조타입으로 가능하다.
    		
    		
    	}//main
    }//end class