匿名オブジェクト


匿名オブジェクト


-匿名オブジェクト:名前なしオブジェクト
-個別に作成できません:作成するには、クラスまたはインプリメンテーションインタフェースを継承する必要があります.
-使用場所:フィールドまたはローカル変数の初期値.主にパラメータのパラメータ値として使用されます.
継承関係:親-子/親-子
接続関係せつぞくかんけい:インタフェース-インプリメンテーションクラス

匿名サブオブジェクトの作成


親タイプのフィールドまたは変数として宣言した後、子オブジェクトを初期値として置換するかどうかを考慮します.親を継承して子クラスを明示し、new演算子を使用して子オブジェクトを作成し、フィールドまたはローカル変数に置き換えます.
// 자식 클래스 선언
class Child extends Parent {	}

class A {
	// 필드에 자식 객체 대입
    	Parent field = new Child();
        void method() {
        // 로컬 변수에 자식 객체 대입
        Parent local = new Child();
    }
}
but. サブクラスを再使用せず、フィールドと変数の初期値としてのみ使用する場合は、匿名のサブオブジェクトを作成して初期値に代入することが望ましい.
부모클래스 필드변수 = new 부모클래스 (매개값, ...) {
	// 필드
    	// 메소드
};
これは実行文なのでセミコロン(;)つまり、貼るべきです.

練習する

// 1. 부모 클래스를 만들어준다
class Parent {
void pM() {	}
void pM1()	{	}
}



class A {
	// 부모 객체 생성과 동시에 자식 객체 생성
	Parent p = new Parent() {
		String cName;
		boolean gender;

		void cM1() {	}
		void cM2() {	}

		// 익명 자식객체는 외부에서 호출할 수 없기때문에
		// 오버라이딩한 메소드에서 사용
		@Override
		void pM() {
			cName="강아지";
			cM1();
		}
		@Override
		void pM1() {
			cName="고양이";
			cM2();
		}
	};
    
    
    	// 클래스 내의 다른 메소드
    	void aMethod() {
		// 익명 객체의 것들이기에
        	// 그 메소드를 넘어가면 호출 불가
//		p.cName = "홍길동";
//		p.gender = true;
//		p.cM1();
		// 이건 부모 클래스의 것을 오버라이딩 한거니 사용 가능
		p.pM();
		p.pM1();
	}
}

練習02-匿名サブオブジェクトの作成


方法フィールドの初期値として代入


親となるPersonを受信してオブジェクトを作成し、その子として匿名のオブジェクトを実装します.
Person field = new Person() {
	// 익명클래스의 메소드는 오버라이딩한 메소드에서 사용하기 위해 작성
	void work() {
		System.out.println("출근합니다");
	}
	@Override
	void wake() {
		System.out.println("6시에 일어납니다");
		// 익명 자식 클래스 메소드 호출
		work();
	}
};

方法ローカル変数値として代入


-クラスにメソッドを作成し、クラスに新しいオブジェクトとして親を作成し、実行内容を作成および使用します.
-コンテンツを実行するには、メソッドで作成したコンテンツを呼び出す必要があります.
void method1() {
	//로컬 변수값으로 대입
	Person localVar = new Person() {
		void walk() {
			System.out.println("산책합니다");
		}
		@Override
		void wake() {
			System.out.println("7시에 일어납니다");
			// 익명 자식 클래스 메소드 호출
			walk();
		}
	};
	//로컬 변수 사용
	localVar.wake();
}

方法パラメータとして扱う


各値を受信するメソッドを作成したら、親にリンクします.
// 매개값으로 Person을 받아 변수 person에 저장
// 들어오는 값을 person.wake()에 받는다
void method2(Person person) {
	person.wake();
}

実装クラスの使用状況を見てみましょう

public class AnonymousEx {
	public static void main(String[] args) {
		Anonymous anony = new Anonymous();
		// wake()는 자식 객체에 있지만
        	// 오버라이딩 한 것이기에 사용 가능한 것
		// 익명 객체 필드 사용
		anony.field.wake();
		
		
		// 익명 객체 로컬 변수 사용
		anony.method1();
		
		
		// 익명 객체 매개값 사용
		// 매개값으로 new Person()을 올려 익명 객체 구현함
		anony.method2(new Person() {
			void study() {
				System.out.println("공부합니다");
			}

			@Override
			void wake() {
				System.out.println("8시에 일어납니다");
				study();
			}
		}
		// 잘보자. } 이거 아니고 )이거다
		);
	}
}
運転状態

練習03-匿名サブオブジェクトの作成


練習フィールドの初期値匿名オブジェクト

public class AnonyEx {
	public static void main(String[] args) {
		A field1 = new A() {
			int childField = 10;
			void childM() {
				System.out.println("익명 구현 메소드 구역");
			}
			@Override
			void aM() {
				System.out.println("익명 자식 구현 객체 값 : " + childField);
				// 익명 자식 구현 메소드 값 호출
				childM();
			}
		};
		field1.aM();
	}
}


class A {
	void aM() {	}
}

ローカル変数匿名オブジェクトの練習

public class AnonyEx2 {
	public static void main(String[] args) {
		A1 local = new A1() {
			double d = 3.14;
			void dA() {
				System.out.println("로컬 익명 객체 메소드");
			}
			@Override
			void a1M() {
				System.out.println("익명 로컬 변수 d의 값 : " + d);
				// 익명 메소드 호출
				dA();
			}
		};
		local.a1M();
	}
}


class A1 { 
	void a1M() {	}
}

隠し子オブジェクトをパラメータとして送信

public class AnonyEx3 {
	public static void main(String[] args) {
		BussinesLogic bl = new BussinesLogic(new A2() {
			// A의 필드
			int num = 10;
			byte num2 = 20;
			char ch = 'C';

			// A의 메소드
			void aChild() {
				System.out.println("A의 메소드 부분");
			}

			@Override
			void a2M() {
				System.out.println("num + 10 : " + (num + 10));
				System.out.println("byte + 20 : " + (num2 + 20));
				System.out.println("char ch : " + ch);
				aChild();
			}
		});
		
	}
}


class BussinesLogic {
	// 생성자
	// 오버로딩 함
	public BussinesLogic() {	}
	public BussinesLogic(A2 a) {	}
}

class A2 {
	void a2M() {	}
}

練習04-匿名オブジェクトの実装

  • インタフェース
  • の作成
    public interface RemoteControl {
    	public void turnOn();
    	public void turnOff();
    }
  • フィールド初期値、ローカル変数値
  • public class Anonymous {
    	// 필드 초기값으로 대입
    	RemoteControl field = new RemoteControl() {
    		@Override
    		public void turnOn() {
    			System.out.println("Tv를 켜겠습니다");
    		}
    		
    		@Override
    		public void turnOff() {
    			System.out.println("Tv를 끄겠습니다");
    		}
    	};
    	
    	void method1() {
    		// 로컬 변수값으로 대입
    		RemoteControl localVar = new RemoteControl() {
    			@Override
    			public void turnOn() {
    				System.out.println("Audio를 켭니다");
    			}
    			
    			@Override
    			public void turnOff() {
    				System.out.println("Audio를 끕니다");
    			}
    		};
    		// 로컬변수 호출
    		localVar.turnOn();
    	}
    	
    	void method2(RemoteControl rc) {
    		rc.turnOn();
    	}
    }
  • クラス呼び出し
  • public class AnonymousEx {
    	public static void main(String[] args) {
    		Anonymous anony = new Anonymous();
    		// 익명 객체 필드
    		anony.field.turnOn();
    		
    		// 익명 객체 로컬 변수 사용
    		anony.method1();
    		
    		// 익명 객체 매개값 사용
    		anony.method2(new RemoteControl() {
    			@Override
    			public void turnOn() {
    				System.out.println("스마트 티비를 켭니다");
    			}
    			@Override
    			public void turnOff() {
    				System.out.println("스마트 티비를 끄겠습니다");
    			}
    		});
    		
    		// 익명 객체 필드
    		anony.field.turnOff();
    	}
    }
    運転図

    練習05-匿名オブジェクトの実装

  • インタフェース
  • の作成
    interface In {
    	void play();
    	void stop();
    }

    2.ローカル変数を他のメソッドから呼び出すことができますか?


    ローカル変数に匿名インプリメンテーションオブジェクトを作成する
    インタフェースでパラメータを交換できますか?
    class BL {
    	// 필드로 익명 구현 객체 만들기
    	In infield = new In() {
    		@Override
    		public void stop() {
    			System.out.println("필드 멈춤");
    		}
    		@Override
    		public void play() {
    			System.out.println("필드 실행");
    		}
    	};
    	
    	// 로컬 변수에 익명 구현 객체 만들기
    	// 만약 변수 선언을 메소드 밖에 한다면
    	In local;
    	void blM1() {
    		// 익명객체 내부에서 매개변수나 로컬 변수를 사용할 경우
    		// 이 변수들은 final을 생략해도 final의 특성을 가진다
    		// 1. 변수 a 를 10이라 초기화했다
    		int a = 10;
    		local = new In() {
    			@Override
    			public void stop() {
    				System.out.println("로컬 멈춤");
    				// 2. 익명객체 내부에서 다른 값에 a를 연산하여 넣는 것은 가능하나
    				int b = a + 10;
    				// a 그 자체의 값을 변경하는 것은 불가능
    				// a += 10;
    			}
    
    			@Override
    			public void play() {
    				System.out.println("로컬 실행");
    			}
    		};
    	}
    	// 다른 메소드에서 로컬변수 호출도 가능하다
    	void yes() {
    		local.stop();
    		local.play();
    	}
    	
    	
    	// 매개변수를 인터페이스로 주고받는 메소드
    	void blM2(In i) {
    		i.stop();
    		i.play();
    	}
    // 매개변수값 으로 익명 구현 객체 만들기
    	void yes2() {
    		blM2(new In() {
    			@Override
    			public void play() {
    				System.out.println("매개변수값 실행");
    			}
    			@Override
    			public void stop() {
    				System.out.println("매개변수값 정지");
    			}
    		});
    	}
    }
  • 呼び出しのプライマリクラス
  • public class AnonyEx {
    	public static void main(String[] args) {
    		BL bl = new BL();
    		
    		bl.infield.play();
    		bl.infield.stop();
    		
    		System.out.println("-----------------");
    		
    		bl.blM1();
    		bl.yes();
    		
    		System.out.println("------------------");
    		
    		bl.blM2(new In() {	
    			@Override
    			public void stop() {
    				System.out.println("메인에서 매개변수 넘겨준 중지");
    			}
    			
    			@Override
    			public void play() {
    				System.out.println("메인에서 매개변수 넘겨준 실행");
    			}
    		});
    		System.out.println("------------------");
    		
    		bl.yes2();
    	}
    }
    運転状態

    メソッドに匿名実装メソッドが含まれている場合、変数はfinalです。


    メソッドに匿名実装オブジェクトが含まれている場合、メソッドのパラメータと領域変数は自動finalとみなされます.
    ただし、メソッド以外で設定した変数フィールドの値は変更できます.
    例)
    public interface Calcu {
    	public int sum();
    }
    
    
    // 메소드 안에 익명구현 객체를 포함하고 있다면
    // 그 매소드의 매개변수와 지역변수는 자동 final 로 간주된다
    class Anonymous {
    	private int field;
    	
    	public void method(final int arg1, int arg2) {
    		final int var1 = 0;
    		int var2 = 0;
    		
    		// 메소드 밖에서 설정한 변수인 field 값은 변경 가능
    		field = 10;
    		
    		// arg1 = 20;
    		// arg2 = 20;
    		
    		// var1 = 30;
    		// var2 = 30;
    		
    		// 익명 구현 객체에서 변수를 참조하고 있기 때문에
    		// 메소드 내에 호출된 변수는 그 상태로 final 고정 되어 값 변경이 불가하다
    		Calcu calc = new Calcu() {
    			@Override
    			public int sum() {
    				// field는 전역변수라 값 변경 가능
    				field = 30;
    				int result = field + arg1 + arg2 + var1 + var2;
    				return result;
    			}
    		};
    		
    		System.out.println(calc.sum());
    	}
    }
    メソッド内で生成された匿名オブジェクトは、メソッドの実行が終了してもhipメモリに存在するため、引き続き使用できます.パラメータまたはローカル変数は、メソッドの実行が終了するとスタックメモリから消え、匿名オブジェクトでは使用できません.
    ->匿名オブジェクト内でメソッドのパラメータまたはローカル変数を使用する場合、これらの変数はfinalプロパティを持つ必要があります.コンパイル時にfinalキーがある場合は、メソッド内部の領域変数にコピーされます.finalキーがない場合は、匿名クラスのフィールドにコピーされます.