[혼공자] 5주차_08~09

다율·2024년 2월 4일
0

2024 혼공자

목록 보기
6/7
post-thumbnail

기본 미션: 클래스를 선언할 때 인터페이스는 어떻게 선언될 수 있는지 정리하기

밑의 인터페이스 선언 부분에 더 자세히 정리해보겠습니다!


08 인터페이스

08-1 인터페이스

  • 객체의 사용방법을 정의
  • 개발코드와 객체가 서로 통신하는 접점 역할(개발 코드는 객체의 내부구조를 알 필요 X 인터페이스의 메소드만 알면 됨)
  • 개발코드 측면에서 코드 변경 없이 실행내용과 리턴값을 다양화 할 수 있다는 장점을 가짐

    개발 코드 > 인터페이스의 메소드 호출 > 인터페이스가 객체의 메소드를 호출

1) 인터페이스 선언

  • 물리적 형태는 클래스와 동일( .java -> .class)
  • 선언하는 방식의 차이
    • 이름은 클래스 이름 작성법과 동일
      • (첫 글자를 대문자로) 등..
  • 상수 필드와 추상 메소드만 가짐(생성자 X)
[public] interface 인터페이스이름 { 
    // 상수
    타입 상수이름 =;
    
    // 추상 메소드
    타입 메소드이름(매개변수, ...);
}

상수 필드 선언

  • 인스턴스 또는 정적(static) 필드 선언 불가
  • 실행 시 데이터를 바꿀 수 없음 (선언 시 초기값 지정)
  • public static final의 특성을 가짐(없으면 자동 추가)
  • 대문자로 작성하고 _로 연결함
	public int MAX_VOLUME = 10;
	public int MIN_VOLUME = 0;

추상 메소드 선언

  • 인터페이스에서 호출된 메소드는 객체에서 실행되므로 추상메소드로 선언함
  • 리턴 타입, 메소드 이름, 매개 변수만 있고 중괄호는 X
  • public abstract의 특성을 가짐(없으면 자동 추가)
	public void turnOn();
	public void turnOff();
	public void setVolume(int volume);

2) 인터페이스 구현

  • 인터페이스가 객체의 메소드를 호출할 때, 객체는 인터페이스에서 정의된 추상메소드와 동일한 이름, 매개 타입, 리턴 타입을 가진 실체 메소드가 있어야 함
    • 이러한 객체를 인터페이스의 구현 객체라고 함
    • 구현 객체를 생성하는 클래스를 구현 클래스라고 함 (모든 메소드는 public으로 명시하기)

구현 클래스

  • 보통의 클래스와 동일, 인터페이스 타입으로 사용할 수 있음을 명시하기 위해 선언부에 implements 키워드 추가
  • 추상메소드의 실체 메소드를 선언해야함
public class 구현클래스이름 implements 인터페이스이름 {
		// 실체 메소드 선언
}

다중 인터페이스 구현 클래스

  • 다수의 인터페이스 타입으로 사용 가능
public class 구현클래스이름 implements 인터페이스A, 인터페이스B {
		// 인터페이스A에 선언된 추상 메소드의 실체 메소드 선언
        // 인터페이스B에 선언된 추상 메소드의 실체 메소드 선언
}

3) 인터페이스 사용

  • (인터페이스 변수에 구현객체 대입 후) 인터페이스로 구현객체 사용하는 법!
public class MyClass {

	// 필드
	RemoteControl rc = new Television();
	
	// 생성자
	MyClass() { }
	
	MyClass(RemoteControl rc) {
		this.rc = rc;
		rc.turnOn();
		rc.setVolume(5);
	}
	
	// 메소드
	void methodA() {
		RemoteControl rc = new Audio();
		rc.turnOn();
		rc.setVolume(5);
	}
	
	void methodB(RemoteControl rc) {
		rc.turnOn();
		rc.setVolume(5);
	}
	
}

08-2 타입 변환과 다형성

  • 코드는 변하지 않고 구현 객체교체함으로써 실행결과가 다양해지는 것

1) 자동 타입 변환

  • 구현 객체인터페이스 타입으로 변환되는 것
	인터페이스 변수 = 구현 객체;

2) 필드의 다형성

  • 상속에서 부모 클래스(=인터페이스), 자식 클래스(=구현 클래스) 느낌
	Car myCar = new Car();
		
	myCar.run();		// 다 HankookTire
		
	myCar.frontLeftTire = new KumhoTire();	
	myCar.frontRightTire = new KumhoTire();
		
	myCar.run();	// 앞쪽 Tire가 KumhoTire로 교체

3) 매개 변수의 다형성

  • 주로 메소드를 호출 시 어떤 구현 객체를 매개값으로 주는지에 따라 실행결과가 다르게 나오는 것
    • 상속 : 매개변수(부모타입), 호출 시(자식객체)
    • 인터페이스 : 매개변수(인터페이스), 호출 시(구현 객체)
public class Driver {
	public void drive(Vehicle vehicle) {
		vehicle.run();
	}
}

// (생략) 실체 메소드를 오버라이딩함

// 실행 코드

public class DriverExample {

	public static void main(String[] args) {
		
		Driver dri = new Driver();
		
		Bus bus = new Bus();
		Taxi taxi = new Taxi();
		
		dri.drive(bus);		// 매개변수의 다형성
		dri.drive(taxi);

	}

}

4) 강제 타입 변환

  • 구현 객체가 인터페이스 타입으로 자동 타입 변환 시, 인터페이스에 선언된 메소드만 사용 가능함
  • 그러므로, 다시 구현 클래스에 선언된 필드와 메소드를 사용해야할 때 강제 타입 변환을 사용함

5) 객체 타입 확인

  • 무작정 강제 타입 변환할 경우, ClassCastException 발생 가능성이 있음
  • 상속에서처럼 instanceof 연산자를 사용
	if(vehi instanceof Bus) {
    	Bus bus = (Bus) vehi;
    }

+ 인터페이스 상속

  • 다중 상속을 허용함
  • 하위 인터페이스를 구현하는 클래스는 하위 인터페이스, 상위 인터페이스의 모든 추상 메소드에 실체 메소드를 가져야 함
  • 상위 인터페이스로 타입 변환이 되면 상위 인터페이스에 선언된 메소드만 사용 가능함
	public interface 하위인터페이스 extends 상위인터페이스1, 상위인터페이스2 {. . .}

09 중첩 클래스와 중첩 인터페이스

09-1 중첩 클래스와 중첩 인터페이스 소개

  • 중첩 클래스란 단어 그대로 클래스 내부에 선언한 클래스를 뜻함
    • 두 클래스의 멤버를 쉽게 접근 가능
    • 외부에 불필요한 관계 클래스를 감춰 코드의 복잡성을 줄임
class ClassName {
	class NestedClassName {
    
    }
}
  • 중첩 인터페이스클래스 내부에 선언한 인터페이스를 뜻함
    • 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를 만들기 위해서 만듦
class ClassName {
	interface NestedInterfaceName {
    
    }
}

1) 중첩 클래스

  • 위치에 따라 두가지로 분류
    • 멤버 클래스 : 클래스의 멤버로서 선언되는 중첩 클래스, 클래스나 객체가 사용중이라면 재사용이 가능
    • 로컬 클래스 : 생성자 또는 메소드 내부에서 선언되는 중첩 클래스, 메소드를 실행할 때만 사용되고 종료되면 사라짐

인스턴스 멤버 클래스

  • static 키워드 없이 중첩 선언된 클래스(정적 필드와 메소드는 선언 불가)

정적 멤버 클래스

  • static 키워드로 선언된 클래스(모든 종류의 필드와 메소드 선언 가능)

로컬 클래스

  • 메소드 내부에서 선언한 중첩 클래스(접근 제한자 및 static을 붙일 수 없음(메소드 내부에서만 사용되므로), 정적 필드와 메소드 선언 불가)

2) 중첩 클래스의 접근 제한

  • 멤버 클래스 내부에서 바깥 클래스의 필드와 메소드에 접근할 때

  • 메소드의 매개변수나 로컬변수를 로컬 클래스에서 사용할 때

  • 예제 비교 하면서 보기!
    바깥 필드와 메소드에서 사용 제한

// 예제
public class B {
	// 인스턴스 필드
	C field1 = new C();
	D field2 = new D();
	
	// 인스턴스 메소드 - 둘 다 가능
	void method1() {
		C var1 = new C();
		D var2 = new D();
	}
	
	// 정적 필드 초기화
	// static C field3 = new C();   정적 멤버 클래스가 아님
	static D field4 = new D();
	
	// 정적 메소드
	static void method2() {
		// C var1 = new C();    정적 멤버 클래스가 아님
		D var2 = new D();
	}
	
	// 인스턴스 멤버 클래스
	class C {}
	
	// 정적 멤버 클래스
	static class D {}
}

멤버 클래스에서 사용 제한

// 예제
public class C {
	int field1;
	void method1() {}
	
	static int field2;
	static void method2() {}
	
	class D {		// 모든 필드와 메소드에 접근 가능
		void method() {
			field1 = 10;
			method1();
			
			field2 = 10;
			method2();
		}
	}
	
	static class E {
		void method() {
			// field1 = 10;    인스턴스 필드와 메소드는 접근 불가
			// method1();
			field2 = 10;
			method2();
		}
	}

}

로컬 클래스에서 사용 제한

  • 메소드의 매개변수나 로컬변수를 로컬 클래스에서 사용할 때의 제한
    • 매개변수와 로컬 변수는 final 특성을 갖고 있음

중첩 클래스에서 바깥 클래스 참조 얻기

  • 클래스 내부에서 this는 객체 자신, 따라서 중첩 클래스에서 this는 바깥 클래스의 객체 참조가 아니라 중첩 클래스의 객체 참조
// 예시
바깥클래스.this.필드;
바깥클래스.this.메소드();

3) 중첩 인터페이스

  • 클래스의 멤버로 선언된 인터페이스, 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를 만들기 위해
  • 인스턴스 멤버 인터페이스와 정적 멤버 인터페이스 모두 가능
class A {
	[static] interface I {
    	void method();
    }
}

09-2 익명 객체

  • 익명 객체이름이 없는 객체를 뜻함, 조건이 있음
    • 어떤 클래스를 상속하거나 인터페이스를 구현해야함
[상속 - 일반적인 경우]
class 클래스이름 extends 부모클래스 { . . . }
부모클래스 변수 = new 클래스 이름();

=>

[상속 - 익명 객체를 선언하는 경우]
부모클래스 변수 = new 부모 클래스() { . . . };
[구현 - 일반적인 경우]
class 클래스 이름 implements 인터페이스 { . . . }
인터페이스 변수 = new 클래스이름();

=>

[구현 - 익명 객체를 선언하는 경우]
인터페이스 변수 = new 인터페이스() { . . . ];

1) 익명 자식 객체 생성

  • 자식 클래스가 재사용되지 않고 특정 위치에서 사용할 경우, 익명 자식 객체를 생성해서 사용하는 것이 좋은 방법임
부모클래스 [필드|변수] = new 부모클래스(매개값, ...) {
	// 필드, 메소드
};
  • 부모 클래스(매개값, ..) {..}은 부모 클래스를 상속하여 자식 클래스를 선언하라는 뜻
    • 그리고 new 연산자가 선언된 자식 클래스를 객체로 생성함
  • 부모클래스(매개값, ..)부모 생성자를 호출하는 것
  • 중괄호 내부에는 필드나 메소드, 메소드 오버라이딩 등 내용 작성
  • 일반 클래스와 다른점! 생성자를 선언할 수 없음
  • 하나의 실행문이므로 마지막에 ; 붙이기

깃허브 링크

https://github.com/dayul/SelfStudy_Java

profile
새싹 개발자 🌱

0개의 댓글