본문 바로가기

Java

반응형

✅ 오전 수업

1. 다형성 with 상속 (Vehicle, Driver)

  • 부모 타입(Vehicle)으로 자식 객체(Bus, Texi)를 다룰 수 있음
  • 오버라이딩된 메서드가 실행됨
driver.drive(new Bus());   // "버스가 달립니다."
driver.drive(new Texi());  // "택시가 달립니다."

2. 추상 클래스 (Phone, Animal)

  • abstract 클래스는 객체 생성 불가, 추상 메서드는 구현 필수
  • 일반 메서드도 가질 수 있음
abstract class Animal {
    void breathe() { ... }
    abstract void sound();
}
  • 다형성 활용:
Animal animal = new Dog();
animal.sound();  // "멍멍"

3. 인터페이스 기본 (RemoteControl)

  • interface는 메서드 선언만 포함
  • 구현 클래스에서 오버라이딩 필수
interface RemoteControl {
    void turnOn();
}
  • 다형성 적용:
RemoteControl rc = new Television();
rc.turnOn();  // "TV를 켭니다."

4. 인터페이스 상수 & 다중 메서드 구현

  • 상수는 모두 public static final
  • 구현 클래스에서 setVolume() 내 볼륨 제한 처리
if(volume > MAX_VOLUME) this.volume = MAX_VOLUME;

✅ 오후 수업

5. default 메서드 (setMute)

  • 인터페이스에서 구현된 기본 메서드
  • 구현 클래스에서 선택적으로 오버라이딩 가능
default void setMute(boolean mute) {
    if (mute) {
        setVolume(MIN_VOLUME);
    } else {
        ...
    }
}​
  • 오버라이딩 예:
@Override
public void setMute(boolean mute) {
    ...
}

6. static 메서드

  • 인터페이스 이름으로 직접 호출
RemoteControl.changeBattery();  // 정적 메서드

7. private 메서드 (Java 9+)

  • default 또는 static 메서드 내부의 중복 코드 정리용
private void defaultCommon() { ... }
private static void staticCommon() { ... }
  • 사용 예:
defaultMethod1() {
    ...
    defaultCommon();
}

📌 17일차 핵심 요약표

개념 설명
다형성 부모 타입으로 자식 객체 처리 가능
추상 클래스 추상 메서드는 구현 필수, 일반 메서드도 포함 가능
인터페이스 구현체에서 메서드 오버라이딩 필수
default 메서드 구현 클래스에서 오버라이딩 가능
static 메서드 인터페이스명으로 직접 호출
private 메서드 중복 코드 정리용 (Java 9+)

 

댓글
반응형

이번 글에서는 자바 9부터 도입된 인터페이스 내 private 메서드를 학습합니다.
default나 static 메서드 안에서 반복되는 공통 코드를 분리할 수 있으며,
외부에서는 보이지 않고 인터페이스 내부에서만 재사용됩니다.


📦 인터페이스 코드 (Service.java)

package ch08.sec07;

public interface Service {
	default void defaultMethod1() {
		System.out.println("defaultMethod1 종속 코드");
		defaultCommon();
	}

	default void defaultMethod2() {
		System.out.println("defaultMethod2 종속 코드");
		defaultCommon();
	}

	private void defaultCommon() {
		System.out.println("defaultMethod 중복 코드A");
		System.out.println("defaultMethod 중복 코드B");
	}

	static void staticMethod1() {
		System.out.println("staticMethod1 종속 코드");
		staticCommon();
	}

	static void staticMethod2() {
		System.out.println("staticMethod2 종속 코드");
		staticCommon();
	}

	private static void staticCommon() {
		System.out.println("staticMethod 중복 코드C");
		System.out.println("staticMethod 중복 코드D");
	}
}

📦 구현 클래스 (ServiceImpl.java)

package ch08.sec07;

public class ServiceImpl implements Service {
	// 따로 메서드 구현하지 않아도 default 메서드 상속됨
}

📌 실행 클래스 (ServiceExample.java)

package ch08.sec07;

public class ServiceExample {
	public static void main(String[] args) {
		Service service = new ServiceImpl();

		service.defaultMethod1();
		System.out.println();
		service.defaultMethod2();
		System.out.println();

		Service.staticMethod1();
		System.out.println();
		Service.staticMethod2();
		System.out.println();
	}
}

💻 실행 결과

defaultMethod1 종속 코드
defaultMethod 중복 코드A
defaultMethod 중복 코드B

defaultMethod2 종속 코드
defaultMethod 중복 코드A
defaultMethod 중복 코드B

staticMethod1 종속 코드
staticMethod 중복 코드C
staticMethod 중복 코드D

staticMethod2 종속 코드
staticMethod 중복 코드C
staticMethod 중복 코드D

💬 코드 설명

  • defaultMethod1() 과 defaultMethod2()는 내부에서 defaultCommon() 호출
    공통 코드 A, B 중복 제거
  • staticMethod1() 과 staticMethod2()는 staticCommon() 호출
    공통 코드 C, D 중복 제거
  • private 메서드는 외부 클래스, 구현 클래스에서 접근 불가
    → 인터페이스 내부에서만 안전하게 재사용

📌 간단 정리

메서드 종류 호출 방식 오버라이딩 접근 범위
default 인스턴스 참조 (service.) 가능 ✅ 구현 클래스 사용 가능
static 인터페이스명으로 호출 불가 ❌ 외부에서 직접 호출
private 내부에서만 호출 불가 ❌ 외부 접근 불가 🔒

💡 포인트 정리

  • private 메서드는 인터페이스 내부 전용 유틸로 사용
  • default, static 메서드 간의 공통 로직 중복 제거
  • 코드 가독성 및 재사용성 향상, 유지보수 쉬워짐
  • 자바 9 이상에서만 사용 가능

📌 정리하자면,
private 메서드는 인터페이스 내부의 코드 정리를 돕는 숨은 도우미 역할을 하며,
외부 노출 없이도 중복 제거와 품질 개선을 이끌어낼 수 있습니다.

댓글
반응형

이번 글에서는 인터페이스에서 정적(static) 메서드를 정의하고 사용하는 방법을 학습합니다.
default 메서드와 달리 static 메서드는 인터페이스 이름으로 직접 호출하며,
보통 공통적인 유틸리티 기능을 정의할 때 사용됩니다.


📦 인터페이스 코드 (RemoteControl.java)

package ch08.sec06;

public interface RemoteControl {
	int MAX_VOLUME = 10;
	int MIN_VOLUME = 0;

	void turnOn();
	void turnOff();
	void setVolume(int volume);

	default void setMute(boolean mute) {
		if (mute) {
			System.out.println("무음 처리합니다.");
			setVolume(MIN_VOLUME);
		} else {
			System.out.println("무음 해제합니다.");
		}
	}

	static void changeBattery() {
		System.out.println("리모콘 건전지를 교환합니다.");
	}
}

✔ static 메서드는 인터페이스명.메서드명()으로 호출
✔ 인스턴스를 생성하지 않아도 사용 가능
✔ 구현 클래스에서 재정의(overriding) 불가


📦 구현 클래스 – TV & 오디오

Television.javaAudio.java는 각각 RemoteControl을 구현하며,
turnOn(), setVolume(), setMute()를 필요에 따라 구현합니다.
(내용 생략 — 이전 글과 동일)


📌 실행 클래스 (RemoteControlExample.java)

package ch08.sec06;

public class RemoteControlExample {
	public static void main(String[] args) {
		RemoteControl rc = new Television();

		rc.turnOn();
		rc.setVolume(5);
		rc.setMute(true);
		rc.setMute(false);

		System.out.println();

		rc = new Audio();
		rc.turnOn();
		rc.setVolume(5);
		rc.setMute(true);
		rc.setMute(false);

		System.out.println();

		RemoteControl.changeBattery(); // static 메서드 직접 호출
	}
}

💻 실행 결과

TV를 켭니다.
현재 TV 볼륨 : 5
무음 처리합니다.
현재 TV 볼륨 : 0
무음 해제합니다.

Audio를 켭니다.
현재 Audio 볼륨 : 5
무음 처리합니다.
현재 Audio 볼륨 : 0
무음 해제합니다.
현재 Audio 볼륨 : 5

리모콘 건전지를 교환합니다.

💬 코드 설명

  • RemoteControl.changeBattery();
    인터페이스명으로 직접 호출하는 정적 메서드
  • 객체를 생성하지 않아도 사용할 수 있으며,
    공통 도구 기능, 초기화 도우미, 상태 확인 등에 주로 사용

📌 간단 정리

요소 특징
default 구현 클래스에서 오버라이딩 가능
static 인터페이스 이름으로 직접 호출, 오버라이딩 불가

💡 포인트 정리

  • static 메서드는 인스턴스 없이 인터페이스 이름으로 직접 호출
  • 구현 클래스와 무관하게 고정된 유틸 기능을 제공할 수 있음
  • default 메서드와 달리 상속(재정의)이 불가능
  • 인터페이스를 도구 모음처럼 활용할 수 있는 구조를 제공

📌 정리하자면,
static 메서드는 인터페이스의 공통적인 기능을 제공하는 유틸리티 역할로,

구현 클래스에 영향을 주지 않고 독립적으로 호출 가능한 장점이 있습니다.

댓글
반응형

이번 글에서는 자바 8부터 지원되는 인터페이스의 default 메서드를 학습합니다.
기존에는 인터페이스에 메서드의 선언만 가능했지만,
이제는 default를 통해 기본 구현까지 포함 가능하며,
필요에 따라 구현 클래스에서 오버라이딩도 가능합니다.


📦 인터페이스 코드 (RemoteControl.java)

package ch08.sec05;

public interface RemoteControl {
	int MAX_VOLUME = 10;
	int MIN_VOLUME = 0;

	void turnOn();
	void turnOff();
	void setVolume(int volume);

	default void setMute(boolean mute) {
		if (mute) {
			System.out.println("무음 처리합니다.");
			setVolume(MIN_VOLUME);
		} else {
			System.out.println("무음 해제합니다.");
		}
	}
}

✔ default 메서드는 몸체를 가진 메서드
✔ 구현 클래스가 오버라이딩하지 않아도 자동 사용됨


📦 구현 클래스 – TV (Television.java)

package ch08.sec05;

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 > MAX_VOLUME)
			this.volume = MAX_VOLUME;
		else if (volume < MIN_VOLUME)
			this.volume = MIN_VOLUME;
		else
			this.volume = volume;
		System.out.println("현재 TV 볼륨 : " + this.volume);
	}
}

✔ setMute()를 오버라이딩하지 않음 → 인터페이스 기본 구현 사용


📦 구현 클래스 – 오디오 (Audio.java)

package ch08.sec05;

public class Audio implements RemoteControl {
	private int volume;
	private int memoryVolume;

	public void turnOn() {
		System.out.println("Audio를 켭니다.");
	}

	public void turnOff() {
		System.out.println("Audio를 끕니다.");
	}

	public void setVolume(int volume) {
		if (volume > MAX_VOLUME)
			this.volume = MAX_VOLUME;
		else if (volume < MIN_VOLUME)
			this.volume = MIN_VOLUME;
		else
			this.volume = volume;
		System.out.println("현재 Audio 볼륨 : " + this.volume);
	}

	@Override
	public void setMute(boolean mute) {
		if (mute) {
			this.memoryVolume = this.volume;
			System.out.println("무음 처리합니다.");
			setVolume(MIN_VOLUME);
		} else {
			System.out.println("무음 해제합니다.");
			setVolume(this.memoryVolume);
		}
	}
}

✔ setMute()를 오버라이딩하여 음소거 전 볼륨 복원 기능 구현


📌 실행 코드 (RemoteControlExample.java)

package ch08.sec05;

public class RemoteControlExample {
	public static void main(String[] args) {
		RemoteControl rc = new Television();

		rc.turnOn();
		rc.setVolume(5);
		rc.setMute(true);   // default 메서드 실행
		rc.setMute(false);  // default 메서드 실행

		System.out.println();

		rc = new Audio();

		rc.turnOn();
		rc.setVolume(5);
		rc.setMute(true);   // 오버라이딩된 메서드 실행
		rc.setMute(false);  // 오버라이딩된 메서드 실행
	}
}

🖥 실행 결과

TV를 켭니다.
현재 TV 볼륨 : 5
무음 처리합니다.
현재 TV 볼륨 : 0
무음 해제합니다.

Audio를 켭니다.
현재 Audio 볼륨 : 5
무음 처리합니다.
현재 Audio 볼륨 : 0
무음 해제합니다.
현재 Audio 볼륨 : 5

📌 간단 정리

구현 클래스 setMute() 동작 방식
Television 인터페이스의 기본 구현 사용
Audio 오버라이딩하여 볼륨 복원 기능 포함

💡 포인트 정리

  • default 메서드는 인터페이스 내에서 기본 구현을 제공
  • 구현 클래스에서 오버라이딩 가능
  • 인터페이스 변경 시 기존 구현 클래스에 영향 최소화
  • 실무에서는 기본 동작을 인터페이스에서 제공하고,
    특수한 클래스에서만 오버라이딩하는 구조로 사용됨

📌 정리하자면,
default 메서드는 인터페이스가 더 유연한 확장을 가능하게 하며, 공통 기능을 강제하지 않고 제공할 수 있는 방법입니다.

댓글
반응형

이번 글에서는 인터페이스의 상수(static final)
구현이 강제되는 추상 메서드들을 통해
일정한 규칙을 정의하고 여러 클래스가 이를 구현하는 방식을 실습합니다.


📦 인터페이스 코드 (RemoteControl.java)

package ch08.sec03;

public interface RemoteControl {
	int MAX_VOLUME = 10; // public static final 자동 포함
	int MIN_VOLUME = 0;

	void turnOn();       // public abstract 자동 포함
	void turnOff();
	void setVolume(int volume);
}

✔ 상수는 public static final, 메서드는 public abstract가 생략되어 있어도 적용됨


📦 구현 클래스 – TV (Television.java)

package ch08.sec03;

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 > MAX_VOLUME)
			this.volume = MAX_VOLUME;
		else if (volume < MIN_VOLUME)
			this.volume = MIN_VOLUME;
		else
			this.volume = volume;
		System.out.println("현재 TV 볼륨 : " + this.volume);
	}
}

📦 구현 클래스 – 오디오 (Audio.java)

package ch08.sec03;

public class Audio implements RemoteControl {
	private int volume;

	public void turnOn() {
		System.out.println("Audio를 켭니다.");
	}

	public void turnOff() {
		System.out.println("Audio를 끕니다.");
	}

	public void setVolume(int volume) {
		if (volume > MAX_VOLUME)
			this.volume = MAX_VOLUME;
		else if (volume < MIN_VOLUME)
			this.volume = MIN_VOLUME;
		else
			this.volume = volume;
		System.out.println("현재 Audio 볼륨 : " + this.volume);
	}
}

📌 실행 클래스 (RemoteControlExample.java)

package ch08.sec03;

public class RemoteControlExample {
	public static void main(String[] args) {
		RemoteControl rc = new Television();
		rc.turnOn();
		rc.setVolume(5);
		rc.turnOff();

		rc = new Audio();
		rc.turnOn();
		rc.setVolume(5);
		rc.turnOff();
	}
}

💻 실행 결과

TV를 켭니다.
현재 TV 볼륨 : 5
TV를 끕니다.
Audio를 켭니다.
현재 Audio 볼륨 : 5
Audio를 끕니다.

💬 코드 설명

  • 인터페이스에 선언된 MAX_VOLUME, MIN_VOLUME는
    공통 볼륨 기준값으로 모든 구현 클래스가 공유
  • 각 구현 클래스(Television, Audio)는 setVolume()에서
    이 상수를 기준으로 볼륨을 제한하고 출력
  • RemoteControl rc = new Audio();
    → 하나의 타입으로 모든 장치를 제어하는 다형성 구조

📌 간단 정리

인터페이스 필드 의미
MAX_VOLUME 최대 볼륨 (10)
MIN_VOLUME 최소 볼륨 (0)

💡 포인트 정리

  • 인터페이스의 필드는 자동으로 상수(static final)로 선언됨
  • 구현 클래스는 인터페이스의 모든 추상 메서드를 반드시 구현해야 함
  • 하나의 타입(RemoteControl)으로 다양한 장치를 제어하는 다형성 적용
  • 유지보수가 쉬운, 표준화된 설계 구조를 만들 수 있음

📌 정리하자면,
인터페이스를 활용하면 기능의 일관성 유지다양한 객체를 하나의 구조로 통제하는 설계를 할 수 있습니다.

댓글
반응형

이번 글에서는 자바의 인터페이스(interface)를 이용해
다형성을 구현하는 방법을 학습합니다.
구현 객체를 바꾸더라도 동일한 타입으로 제어할 수 있는 구조를 통해
코드의 유연성과 확장성을 높이는 설계를 체험합니다.


📦 인터페이스 (RemoteControl.java)

package ch08.sec02;

public interface RemoteControl {
	public void turnOn(); // 추상 메서드
}

✔ interface로 선언된 타입은
✔ 모든 메서드가 자동으로 public abstract (본문 없음)


📦 구현 클래스 - TV (Television.java)

package ch08.sec02;

public class Television implements RemoteControl {
	public void turnOn() {
		System.out.println("TV를 켭니다.");
	}
}

📦 구현 클래스 - 오디오 (Audio.java)

package ch08.sec02;

public class Audio implements RemoteControl {
	public void turnOn() {
		System.out.println("Audio를 켭니다.");
	}
}

📌 실행 클래스 (RemoteControlExample.java)

package ch08.sec02;

public class RemoteControlExample {
	public static void main(String[] args) {
		RemoteControl rc = new Television();
		rc.turnOn(); // TV를 켭니다.

		rc = new Audio();
		rc.turnOn(); // Audio를 켭니다.
	}
}

💻 실행 결과

TV를 켭니다.
Audio를 켭니다.

💬 코드 설명

  • RemoteControl은 인터페이스 → 기능의 틀(규칙)만 정의
  • Television, Audio는 RemoteControl을 implements 하여 기능 구현
  • 실행 클래스에서는 RemoteControl 인터페이스 변수로
    구현 객체를 교체하며 동일한 메서드(turnOn()) 실행

📌 간단 정리

타입 메서드 동작 결과
Television() TV를 켭니다.
Audio() Audio를 켭니다.

💡 포인트 정리

  • 터페이스기능 명세만 정의하고, 객체는 별도로 구현
  • 인터페이스를 통해 다양한 객체를 하나의 타입으로 다룰 수 있음
  • 인터페이스는 다중 구현이 가능, 유지보수에 유리한 구조
  • 개발 시 코드를 유연하게 설계하고 교체가 쉬움

📌 정리하자면,
인터페이스는 "이 객체가 어떤 기능을 제공하는가"에 집중하여 설계하고, 다형성을 적극적으로 활용할 수 있게 해줍니다.

댓글
반응형

이번 글에서는 추상 클래스 내 추상 메서드를 정의하고,
자식 클래스에서 이를 오버라이딩하여 개별 동작을 구현하는 방법을 학습합니다.
이를 통해 공통 인터페이스는 유지하면서,
각 객체가 자신만의 동작을 정의할 수 있게 됩니다.


📦 추상 클래스 (Animal.java)

package ch07.sec10.exam02;

public abstract class Animal {
	public void breathe() {
		System.out.println("숨을 쉽니다.");
	}

	public abstract void sound(); // 추상 메서드 (몸체 없음)
}

📦 자식 클래스 – 강아지 (Dog.java)

package ch07.sec10.exam02;

public class Dog extends Animal {
	public void sound() {
		System.out.println("멍멍");
	}
}

📦 자식 클래스 – 고양이 (Cat.java)

package ch07.sec10.exam02;

public class Cat extends Animal {
	public void sound() {
		System.out.println("야옹");
	}
}

📌 실행 클래스 (AbstractMethodExample.java)

package ch07.sec10.exam02;

public class AbstractMethodExample {
	public static void main(String[] args) {
		Dog dog = new Dog();
		Cat cat = new Cat();

		dog.sound(); // 멍멍
		cat.sound(); // 야옹

		animalSound(new Dog());
		animalSound(new Cat());
	}

	public static void animalSound(Animal animal) {
		animal.sound(); // 다형성 활용
	}
}

🖥 실행 결과

멍멍
야옹
멍멍
야옹

💬 코드 설명

  • Animal 클래스는 추상 클래스이며,
    sound() 메서드는 추상 메서드(몸체 없음)로 선언됨
  • 자식 클래스인 Dog, Cat은 반드시 sound()를 오버라이딩해야 함
    → 하지 않으면 컴파일 오류 발생
  • animalSound(Animal animal) 메서드는
    부모 타입으로 자식 객체를 받아 다형성을 적용한 예시

📌 간단 정리

클래스 오버라이딩한 메서드 동작
Dog sound() → 멍멍 출력
Cat sound() → 야옹 출력

💡 포인트 정리

  • 추상 메서드는 자식 클래스가 반드시 구현해야 함
  • 추상 클래스는 공통 동작(breathe) + 개별 동작(sound) 설계에 적합
  • animalSound() 메서드는 다형성을 이용하여 다양한 객체 처리
  • 추상 클래스는 템플릿 설계로 자주 사용됨

📌 정리하자면,
추상 메서드를 통해 강제적으로 메서드를 구현하게 만들고,
다형성을 통해 확장성과 유연성을 확보할 수 있는 구조를 만들 수 있습니다.

댓글
반응형

이번 글에서는 자바의 추상 클래스(Abstract Class)에 대해 학습합니다.
공통된 속성과 기능은 추상 클래스에 정의하고,
객체는 직접 생성할 수 없으며, 자식 클래스에서 기능을 완성하여 사용하게 됩니다.


📦 추상 클래스 (Phone.java)

package ch07.sec10.exam01;

public abstract class Phone {
	String owner;

	Phone(String owner) {
		this.owner = owner;
	}

	void turnOn() {
		System.out.println("폰 전원을 켭니다.");
	}

	void turnOff() {
		System.out.println("폰 전원을 끕니다.");
	}
}

📦 자식 클래스 (SmartPhone.java)

package ch07.sec10.exam01;

public class SmartPhone extends Phone {
	SmartPhone(String owner) {
		super(owner);
	}

	void internetSearch() {
		System.out.println("인터넷 검색을 합니다.");
	}
}

📌 실행 클래스 (PhoneExample.java)

package ch07.sec10.exam01;

public class PhoneExample {
	public static void main(String[] args) {
		// Phone phone = new Phone(); // (X) 추상 클래스는 객체 생성 불가

		SmartPhone sp = new SmartPhone("홍길동");
		sp.turnOn();
		sp.internetSearch();
		sp.turnOff();
	}
}

💬 코드 설명

  • Phone 클래스는 abstract 키워드가 붙은 추상 클래스
    • 생성자와 일반 메서드를 가질 수 있음
    • 하지만 객체를 직접 생성할 수 없음
  • SmartPhone 클래스는 Phone을 상속받은 자식 클래스
    • 생성자를 통해 owner 값 초기화
    • 추가 기능 internetSearch() 정의
  • PhoneExample에서는 Phone은 생성 불가
    • 대신 SmartPhone 객체를 생성하여 상속받은 메서드 사용

💻 실행 결과

폰 전원을 켭니다.
인터넷 검색을 합니다.
폰 전원을 끕니다.

📌 간단 정리

추상 클래스 특징 설명
abstract 키워드 클래스 앞에 붙여 선언
객체 생성 불가 new로 인스턴스 생성 불가
생성자 존재 가능 자식 클래스에서 super()로 호출
상속 필수 자식 클래스에서 사용 가능
일반 메서드 정의 가능 추상 메서드 없이도 추상 클래스 사용 가능

💡 포인트 정리

  • 추상 클래스는 공통 기능을 미리 정의하거나,
    일부만 구현하고 나머지는 자식 클래스에게 맡기는 구조
  • 객체 생성은 불가능하지만, 상속을 통해 자식 클래스에서 사용 가능
  • 공통 기능은 그대로 상속하고, 필요한 기능은 자식 클래스에서 추가하거나 재정의
  • 다형성 + 템플릿 설계 시 매우 유용하게 사용됨
댓글