본문 바로가기
혼공단/혼공자

혼공자 - 5주차

by 珠延 2024. 2. 5.

Chap 8-1 인터페이스

 

🔗 인터페이스

  • 개발 코드와 객체가 서로 통신하는 접점 역할
  • 개발 코드가 인터페이스의 메소드를 호출하면 인터페이스는 객체의 메소드를 호출시킨다.

🔗 인터페이스의 특징

  • 상수 필드추상 메소드만 가진다.
  • 인터페이스는 객체로 생성할 수 없기에 생성자를 가질 수 없다. (/자식 클래스는 객체를 생성할 수 있다.)
  • 자식 클래스에서 추상 메서드를 재정의 해주어야 된다.

🔗 인터페이스 선언

인터페이스 선언은 class 키워드 대신에 interface 키워드를 사용한다.
[public] interface 인터페이스 이름 {...}
public interface RemoteControl{
	//상수(static, final)
    public int MAX_VOLUME = 10;
    public int MIN_VOLUME = 0;
    
    //추상 메소드(abstract로 생성)
    public void turnOn();
    public void turnOff();
    public void setVolume(int volume);
}

 

🔗 인터페이스 구현

public class 구현클래스이름 implements 인터페이스이름{
	//인터페이스에 선언된 추상 메소듸의 실체 메소드 선언
}


① implments로 인터페이스를 구현시킨다.

public class Television implements RemoteControl{ //인터페이스 생성
	//상수
	private int volume;
	
	//추상 메소드 오버라이드
	public void turnOn() {
		System.out.println("TV를 켭니다.");
	}
	
	public void turnOff() {
		System.out.println("TV를 끕니다.");
	}
	
	public void setVolume(int volume) {
		if(volume>RemoteControl.MAX_VOLUME) {
			this.volume = RemoteControl.MAX_VOLUME;
		}
		else if(volume<RemoteControl.MIN_VOLUME) {
			this.volume = RemoteControl.MIN_VOLUME;
		}else {
			this.volume = volume;
		}
		System.out.println("현재 TV 볼륨 : "+this.volume);
	}
}


② 인터페이스를 구현 후 추상 메소드를 재정의 해준다.

	public static void main(String[] args) {
		 Television tv = new Television();
		 Audio audio = new Audio();
		
		 tv.turnOff();
		 tv.turnOn();
		 tv.setVolume(5);
		 System.out.println();

 
③ 재정의한 메소드를 호출해준다!

 

🔗 인터페이스 사용

클래스를 선언할 때 인터페이스는 필드, 생성자, 또는 메소드의 매개 변수, 생성자, 또는 메소드의 로컬 변수로 선언될 수 있다.
더보기
① 인터페스가 필드 타입으로 사용될 경우 : 필드에 구현 객체를 대입할 수 있다.
MyClass myclass = new MyClass();
myClass.rc.turnOn();
myclass.rc.setVolume(5);​

 

 

생성자의 매개 변수 타입으로 사용될 시:
 new 연산자로 객체를 생성할 때 구현 객체를 생성자의 매개값으로 대입할 수 있다.

myClass ( remoteControl re) {
	this.rc = rc;
    rc.turnOn();
    rc.setVolume(5);
}

 

로컬 변수 타입으로 사용될 시 : 변수에 구현 객체를 대입할 수 있다.

void methodA(){
	RemoteControl rc = new Audio();
    rc.turnOn();
    rc.setVolime(%);
}

 

메소드의 매개 변수 타입으로 사용될 시

- 메소드 호출 시 구현 객첵를 매개 값으로 대입할 수 있다.

void methodB(RemoteControl rc){
		rc.turnOn();
        rc.setVolume(5);
}

 

대입이 된 후에는 재정의된 구현 객체의 메소드를 호출할 수 있다.


Chap 8-1 타입 변환과 다형성

🔗 인터페이스의 다형성

  • 구현 객체를 교체하여 실행결과가 다양해지는 것

🔗 자동 타입 변환

자동 타입 변환 : 구현 객체가 인터페이스 타입으로 변환되는 것
인터페이스 변수 = 구현객체;​

 

🔗 필드의 다형성

public interface Tire {
	public void roll(); 
}

인터페이스 생성

public class HkTire implements Tire {
	public void roll() {
		//Tire 인터페이스 구현
		System.out.println("한국 타이어가 굴러갑니다."); 
	}
}

public class GhTire implements Tire {
	public void roll() {
		//Tire 인터페이스 구현
		System.out.println("금호 타이어가 굴러갑니다."); 
	}
}

구현 클래스 (roll메소드를 재정의 해준다)

public class Car {
		//4개의 HkTire 타입 필드를 가짐
		Tire frontLeftTire = new HkTire();
		Tire frontRightTire = new HkTire();
		Tire backLeftTire = new HkTire();
		Tire backRightTire = new HkTire();
	
	void run() {
		// 인터페이스에서 설명된 roll() 메소드 호출
		frontLeftTire.roll();
		frontRightTire.roll();
		backLeftTire.roll();
		backRightTire.roll();
	}
}

필드 타입으로 타이어 인터페이스를 선언하면 필드값으로 한국 타이어 또는 금호 타이어 객체를 대입할 수 있다.

public class CarMain {

	public static void main(String[] args) {
		Car mycar = new Car();
		
		mycar.run(); //HkTire
		
        //초기갑으로 대입한 구현 객체 대신 다른 구현 객체를 대입할 수 있다.
		mycar.frontLeftTire = new GhTire();  
		mycar.frontRightTire = new GhTire();
		
		mycar.run();
	}

}

 

mycar.frontLeftTire = new GhTire();  
mycar.frontRightTire = new GhTire();

GhTIre로 교체된 후에는 GhTire 객체의 roll() 메소드가 호출된다.
Car의 run()메소드를 수정하지 않아도 다양한 roll() 메소드의 실행결과를 얻을 수 있다.
이게 바로 필드의 다형성이다.!

 

🔗 매개 변수의 다형성

매개 변수의 다형성 
1) 매개 변수의 타입이 인터페이스일 경우 어떠한 구현 객체도 매개값으로 사용가능
2) 어떤 구현 객체가 제공되느냐에 따라 메소드의 실행결과는 다양해진다.
public class Driver {
	public void drive(Vehicle vehicle) { //인터페이스 타입 매개 변수
		vehicle.run();
	}

}​
매개 변수의 인터페이스화
// 인터페이스 생성
public interface Vehicle {
	public void run();
} 

//구현 클래스 생성
public class Bus implements Vehicle {
	public void run() {
		System.out.println("버스가 달립니다.");
	}

}

public class Taxi implements Vehicle{
	public void run() {
		System.out.println("택시가 달립니다.");
	}
}​

 

public class DriveMain {

	public static void main(String[] args) {
		Driver driver = new Driver();
		
		Bus bus = new Bus();
		Taxi taxi = new Taxi();
		
		driver.drive(bus); //자동 타입 변환 : Vehicle vehicle = bus;
		driver.drive(taxi); //자동 타입 변환 : Vehicle vehicle = taxi;

	}

}

 

이렇게 매개 변수를 이용하여 다양한 메소드를 실행할 수 있도록 한다.

 

🔗 강제 타입 변환

구현클래스 변수 = (구현클래스) 인터페이스변수;
인터페이스 변수를 구현 클래스 변수로 강제타입 변환 시킨다.
public interface Excercise {
	public void run();
}

public class Jumprope implements Excercise{
		public void run() {
			System.out.println("줄넘기를 합니다."); //메소드 오버라이딩
		}
		public void checkFar() {
			System.out.println("심박수를 확인합니다.");
		}

}

 

public class ExcrciseMain {

	public static void main(String[] args) {
		Excercise ex  = new Jumprope();
		
		ex.run();
		//jr.checkFar();
		
		Jumprope jr = (Jumprope)ex; //강제 타입 변환
		jr.run();
		jr.checkFar();
	}

}

인터페이스 변수를 구현 클래스  변수로 강제 타입 시켰다.

 


🔗 중첩 클래스

  • 클래스 내부에 선언한 클래스
  • 두 클래스의 멤버들을 서로 쉽게 접근
  • 코드의 복잡성을 줄임
중첩 클래스는 멤버 클래스와 로컬 클래스로 분류 된다.
멤버 클래스 인스턴스 멤버
클래스
class A{
     class B{ ... }
}
A객체를 생성해야만 사용할 수 있는 B 클래스
정적 멤버 클래스 class A{
   static class B{...}
}
A 클래스로 바로 접근할 수 있는 B 클래스
로컬 클래스 class A{
 void method(){
  class B {...}
}
}
 

 

🔗 인스턴스 멤버 클래스

  • static 키워드 없이 중첩 선언된 클래스
  • 인스턴스 필드와 메소드만 선언이 가능하다
  • 정적 필드와 메소드는 선언할 수 없다.
class A{
	class B{
    B() {} //생성자
    int field1; //인스턴트 필드
    void method(); //인스턴트 메소드
    }
}

 
A 클래스 외부에서 객체 생성하는 법

A a = new A();
A.B b = a.new B();
b.field1 = 3;
b.method();

 
A 클래스 내부에서 객체 생성하는 법

class A{
	class B{...}
	
    void methodA(){
    B b = new B();
    b.field1 = 3;
    b.method1();
    }
}

 
 

🔗 정적 멤버 클래스

정적 멤버 클래스 : static 키워드로 선언된 클래스, 모든 종류의 필드와 메소드를 선언할 수 있다.

class A{
	static class C{
    C(){}//생성자
    int field; //인스턴스 필드
    static int field2; //정적 필드
    void method1(){} //인스턴스 메소드
    static void methoc2(){} //정적 메소드
    }
}​

클래스 외부에서 정젖ㄱ 멤버 클래스 C의 객체를 생성하려면 A 객체를 생성할 필요가 없다.⬇️⬇️
A.C c = new A.C();
c.field1 = 3; //인스턴스 필드 사용
c.method1(); //인스턴스 메소드 호출
A.C.field2 = 3; //정적 필드 사용
A.C.method2();  //정적 메소드 호출

 

 

🔗 로컬 클래스

로컬 클래스 : 중첩 클래스의 메소드 내에서도 선언할 수 있는 클래스
- 접근 제한자 및 static을 붙일 수 없다( 메소드 내부에서만 사용죄기 때문)
- 인스턴스 필드와 메소드만 선언가능
- 정적 필드와 메소드는 선언 X

void methoid(){
	//로컬 클래스
    class D{
     D() {} //생성자
     int field1;
     void method1() {}
    } //class D
    
    D d = new D(); //메소드 내에서 객체 생성 및 사용
    d.field1 = 3;
    d.method1();
}​

로컬 클래스는 메소드가 실행될 때 메소드 내에서 객체를 생성하고 사용해야 한다.

 

🔗 중첩 클래스의 접근 제한

바깥 필드와 메소드에서 사용 제한
- 바깥 클래스에서 인스턴스 멤버 클래스를 사용할 때 제한이 있다.

 


멤버 클래스에서 사용 제한 

    • 인스턴스 멤버 클래스는 바깥 클래스의 모든 필드와 모든 메소드에 접근 가능
    • 정적 멤버 클래스인스턴스 필드와 메소드에 접근할 수 없다.

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

바깥클래스.this.필드
바깥클래스.this.메소드();

이번 기본 미션 클래스 선언시 인터페이스를 선언하는 방법 정리하기

 클래스 선언시 인터페이스를 선언하는 방법 정리하기

 

🔗 기본 미션

더보기
 클래스 선언시 인터페이스를 선언하는 방법 정리하기

 

인터페이스 선언은 class 키워드 대신에 interface 키워드를 사용한다!

public interface Exam{

}

 

'혼공단 > 혼공자' 카테고리의 다른 글

[ 혼공단 11기 회고록 ]  (0) 2024.02.18
혼공자 - 6주차  (1) 2024.02.13
혼공자 - 4주차  (1) 2024.01.29
혼공자 - 3주차  (1) 2024.01.21
혼공자 - 2주차  (0) 2024.01.13