2026. 1. 15. 13:28ㆍ대우개발원 수업 내용/Java 정리
여러 클래스의 공통된 특성(필드, 메소드)를 추출해서 선언한 것을 추상 클래스라고 한다.
추상 클래스
▪ 실체 클래스(객체 생성용 클래스)들의 공통적인 특성(필드, 메소드)을 추출하여 선언한 것
▪ 추상 클래스와 실체 클래스는 부모, 자식 클래스로서 상속 관계를 가짐
[추상 클래스의 용도]
추상 클래스의 용도
▪ 실체 클래스에 반드시 존재해야할 필드와 메소드의 선언(실체 클래스의 설계 규격 - 객체 생성용이 아님)
▪ 실체 클래스에는 공통된 내용은 빠르게 물려받고, 다른 점만 선언하면 되므로 시간 절약
예제코드
실행 사진 및 출력결과

출력결과
폰 전원을 켭니다.
인터넷 검색을 합니다.
폰 전원을 끕니다.
실행코드
package sec01.Phone;
public abstract class Phone {
// 필드
public String owner;
// 생성자
public Phone(String owner) {
this.owner = owner;
}
// 메소드
public void turnOn() {
System.out.println("폰 전원을 켭니다.");
}
public void turnOff() {
System.out.println("폰 전원을 끕니다.");
}
}
package sec01.Phone;
public class SmartPhone extends Phone {
//생성자
public SmartPhone(String owner) {
super(owner);
}
// 메소드
public void internetSearch() {
System.out.println("인터넷 검색을 합니다.");
}
}
package sec01.Phone;
public class PhoneEx {
public static void main(String[] args) {
// Phone = phone = new Phone(); // (x)
SmartPhone smartPhone = new SmartPhone("홍길동");
smartPhone.turnOn();
smartPhone.internetSearch();
smartPhone.turnOff();
}
}
[ 추상 클래스 선언]
추상 클래스 선언
▪ abstract 키워드
• 상속 통해 자식 클래스만 만들 수 있게 만듬(부모로서의 역할만 수행)
▪ 추상 클래스도 일반 클래스와 마찬가지로 필드, 생성자, 메소드 선언 할 수 있음
▪ 직접 객체를 생성할 수 없지만 자식 객체 생성될 때 객체화 됨.
• 자식 생성자에서 super(…) 형태로 추상 클래스의 생성자 호출
- 상속받는 클래스가 일반 클래스라면 반드시 오버라이딩해야 한다.
- 상속받는 클래스도 추상 클래스라면 오버라이딩하지 않아도 괜찮다
실행 사진 및 출력결과

출력결과
멍멍
야옹
------
멍멍
야옹
------
실행코드
package sec01.Animal;
public abstract class Animal{
public String kind;
public void breath(){
System.out.println("숨을 쉽니다.");
}
public abstract void sound();
}
package sec01.Animal;
public class Cat extends Animal{
// “Cat 클래스는 Animal 로부터 상속받은 추상 메서드 sound()를 구현(오버라이딩)해야 한다”
public Cat(){
this.kind = "포유류";
}
@Override
public void sound(){
System.out.println("야옹");
}
}
package sec01.Animal;
public class Dog extends Animal{
// “Dog 클래스는 Animal 로부터 상속받은 추상 메서드 sound()를 구현(오버라이딩)해야 한다”
public Dog(){
this.kind = "포유류";
}
@Override
public void sound(){
System.out.println("멍멍");
}
}
package sec01.Animal;
public class AnimalEx {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
dog.sound();
cat.sound();
System.out.println("------");
//변수의 자동 타입 변환
Animal animal = null;
animal = new Dog();
animal.sound();
animal = new Cat();
animal.sound();
System.out.println("------");
}
public static void animalSound(Animal animal) {
animal.sound();
}
}
[추상 메소드와 재정의]
추상 메소드
▪ 메소드 선언만 통일하고 실행 내용은 실체 클래스마다 달라야 하는 경우
▪ abstract 키워드로 선언되고 중괄호가 없는 메소드
▪ 하위 클래스는 반드시 재정의해서 실행 내용을 채워야 함.
[sealed 클래스]
▪ Java 15부터 무분별한 자식 클래스 생성을 방지하기 위해 봉인된 클래스가 도입
▪ sealed 키워드를 사용하면 permits 키워드 뒤에 상속 가능한 자식 클래스를 지정
▪ final은 더 이상 상속할 수 없다는 뜻이고, non-sealed는 봉인을 해제한다는 뜻
예제코드 Person
실행 사진 및 출력결과

출력결과
하는 일이 결정되지 않았습니다.
제품을 생산합니다.
생산 관리를 합니다.
제품을 기획합니다.
실행코드
package sec01.Person;
public sealed class Person permits Employee, Manager{
// 필드
public String name;
// 메소드
public void work() {
System.out.println("하는 일이 결정되지 않았습니다.");
}
}
package sec01.Person;
public final class Employee extends Person {
@Override
public void work() {
System.out.println("제품을 생산합니다.");
}
}
package sec01.Person;
public class Director extends Manager {
@Override
public void work() {
System.out.println("제품을 기획합니다.");
}
}
package sec01.Person;
public class SealedEx {
public static void main(String[] args) {
Person p = new Person();
Employee e = new Employee();
Manager m = new Manager();
Director d = new Director();
p.work();
e.work();
m.work();
d.work();
}
}
Quiz. CalculatorEx.java
public abstract class Calculator {
public abstract int add(int a, int b);
public abstract int subtract(int a, int b);
public abstract double average(int[] a);
}
위의 Calculator클래스를 상속받아 CalcMethod클래스에서 메소드들을
재정의 하고 CalculatorEx클래스를 통해 결과를 출력하세요
출력예시)
ex> a=2, b=3, int[] array = { 1, 2, 3, 4, 5 };
add: 5
subtract: -1
average: 3.0
실행 사진 및 출력결과

출력결과
add: 5
subtract: -1
average: 3.0
실행코드
package quiz.Calculator;
public abstract class Calculator {
public abstract int add(int a, int b);
public abstract int subtract(int a, int b);
public abstract double average(int[] a);
}
package quiz.Calculator;
public class CalcMethod extends Calculator {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int subtract(int a, int b) {
return a - b;
}
@Override
public double average(int[] a) {
double sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
return (double) sum / a.length;
}
}
package quiz.Calculator;
public class CalculatorEx {
public static void main(String[] args) {
// 값을 미리 넣지 않고 안에서 따로따로 넣기
CalcMethod cal = new CalcMethod();
System.out.println("add: " + cal.add(2, 3));
System.out.println("subtract: " + cal.subtract(2, 3));
System.out.println("average: " + cal.average(new int[] { 1, 2, 3 ,4 , 5}));
//위에서 선언해서 쓰는 방법도 가능
// int a = 2;
// int b = 3;
// int[] array = {1, 2, 3, 4, 5};
//
// Calculator cal = new CalcMethod(); // 다형성
//
// System.out.println("add: " + cal.add(a, b));
// System.out.println("subtract: " + cal.subtract(a, b));
// System.out.println("average: " + cal.average(array));
}
}
Quiz. HttpServletExample.java
public abstract class HttpServlet {
public abstract void service();
}
위의 HttpServlet 클래스를 상속받아 LoginServlet 클래스와 FileDownloadServlet 클래스에서 메소드들을 재정의 하고
HttpServletExample 클래스를 통해 결과를 출력하세요
출력예시)
로그인 합니다.
파일 다운로드 합니다.
실행 사진 및 출력결과

출력결과
로그인 합니다.
파일 다운로드 합니다.
실행코드
package quiz.HttpServletExample;
public abstract class HttpServlet {
public abstract void service();
}
package quiz.HttpServletExample;
public class LoginServlet extends HttpServlet{
@Override
public void service() {
System.out.println("로그인 합니다.");
}
}
package quiz.HttpServletExample;
public class FileDownloadServlet extends HttpServlet {
@Override
public void service() {
System.out.println("파일 다운로드 합니다.");
}
}
package quiz.HttpServletExample;
public class HttpServletEx {
public static void main(String[] args) {
method(new LoginServlet());
method(new FileDownloadServlet());
}
public static void method(HttpServlet servlet) {
servlet.service();
}
}
[인터페이스]
▪ 두 객체를 연결하는 역할
▪ 다형성 구현에 주된 기술
인터페이스란 객체의 사용 방법을 정의한 타입이다.
인터페이스를 통해 다양한 객체를 동일한 사용 방법으로 이용할 수 있다.
인터페이스를 이용해서 다형성을 구현할 수 있다.
인터페이스 (interface)
▪ 개발 코드는 인터페이스를 통해서 객체와 서로 통신한다.
▪ 인터페이스의 메소드 호출하면 객체의 메소드가 호출된다.
▪ 개발 코드를 수정하지 않으면서 객체 교환이 가능하다.
[인터페이스 선언]
▪ 인터페이스 선언은 class 키워드 대신 interface 키워드를 사용
▪ 접근 제한자로는 클래스와 마찬가지로 같은 패키지 내에서만 사용 가능한 default,
패키지와 상관없이 사용하는 public을 붙일 수 있음
▪ ~.java 형태 소스 파일로 작성 및 컴파일러 통해 ~class 형태로 컴파일된다.
▪ 클래스와 물리적 파일 형태는 같으나 소스 작성 내용이 다르다.
▪ 인터페이스는 객체로 생성할 수 없으므로 생성자 가질 수 없다.
- 인스턴스의 필드는 무조건 상수이다
상수 필드 (constant field) 선언
▪ 데이터를 저장할 인스턴스 혹은 정적 필드 선언 불가
▪ 상수 필드만 선언 가능
▪ 상수 이름은 대문자로 작성하되 서로 다른 단어로 구성되어 있을 경우 언더바(_)로 연결
상수 필드
▪ 인터페이스는 public static final 특성을 갖는 불변의 상수 필드를 멤버로 가질 수 있음
▪ 인터페이스에 선언된 필드는 모두 public static final 특성을 갖기 때문에 public static final을
생략해도 자동으로 컴파일 과정에서 붙음
▪ 상수명은 대문자로 작성하되, 서로 다른 단어로 구성되어 있을 경우에는 언더바( _)로 연결
추상 메소드 선언
▪ 인터페이스 통해 호출된 메소드는 최종적으로 객체에서 실행
▪ 인터페이스의 메소드는 실행 블록 필요 없는 추상 메소드로 선언
▪ 리턴 타입, 메소드명, 매개변수만 기술되고 중괄호 { }를 붙이지 않는 메소드
▪ public abstract를 생략하더라도 컴파일 과정에서 자동으로 붙음
▪ 추상 메소드는 객체 A가 인터페이스를 통해 어떻게 메소드를 호출할 수 있는지 방법을 알려주는 역할
예시 코드 ↓
package sec02;
public interface RemoteControl {
// 필드 -> 인터페이스에서 필드는 무조건 상수이다
// 상수라서 대문자
public static final int MAX_VOLUME = 10;
int MIN_VOLUME = 0;
// 추상 메소드
public abstract void turnOn();
void turnOff();
void setVolume(int volume);
}
구현 (implement) 클래스
▪ 인터페이스에서 정의된 추상 메소드를 재정의해서 실행내용을 가지고 있는 클래스
▪ 클래스 선언부에 implements 키워드 추가하고 인터페이스 이름 명시
예시 코드 ↓
package sec02;
public class Television implements RemoteControl{
// 필드
private int volume;
//turnOn() 추상 메소드의 실체 메소드
public void turnOn() {
System.out.println("TV를 켭니다.");
}
//turnOff() 추상 메소드의 실체 메소드
public void turnOff() {
System.out.println("TV를 끕니다.");
}
//setVolume() 추상 메소드의 실체 메소드
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);
}
}
▪ 인터페이스에 정의된 추상 메소드에 대한 실행 내용이 구현
▪ implements 키워드는 해당 클래스가 인터페이스를 통해 사용할 수 있다는 표시이며,
인터페이스의 추상 메소드를 재정의한 메소드가 있다는 뜻
인터페이스와 구현 클래스 사용 방법
▪ 인터페이스 변수 선언하고 구현 객체를 대입
[변수 선언과 구현 객체 대입]
▪ 인터페이스는 참조 타입에 속하므로 인터페이스 변수에는 객체를 참조하고 있지 않다는 뜻으로
null을 대입할 수 있음
▪ 인터페이스를 통해 구현 객체를 사용하려면, 인터페이스 변수에 구현 객체의 번지를 대입해야 함
아래 최종 코드
* 상수필드 선언해놨을때 상수필드 같은 경우에는 인터페이스로 객체 생성 없이 바로 접근을 해서 사용가능
실행 사진 및 출력결과

출력결과
리모콘 최대 볼륨10
리모콘 최저 볼륨0
TV를 켭니다.
TV를 끕니다.
Audio를 켭니다.
Audio를 끕니다.
실행코드
package sec02;
public interface RemoteControl {
// 필드 -> 인터페이스에서 필드는 무조건 상수이다
// 상수라서 대문자
public static final int MAX_VOLUME = 10;
int MIN_VOLUME = 0;
// 추상 메소드
public abstract void turnOn();
void turnOff();
void setVolume(int volume);
}
package sec02;
public class Television implements RemoteControl{
// 필드
private int volume;
//turnOn() 추상 메소드의 실체 메소드
public void turnOn() {
System.out.println("TV를 켭니다.");
}
//turnOff() 추상 메소드의 실체 메소드
public void turnOff() {
System.out.println("TV를 끕니다.");
}
//setVolume() 추상 메소드의 실체 메소드
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);
}
}
package sec02;
public class Audio implements RemoteControl {
// 필드
private int volume;
//turnOn() 추상 메소드의 실체 메소드
public void turnOn() {
System.out.println("Audio를 켭니다.");
}
//turnOff() 추상 메소드의 실체 메소드
public void turnOff() {
System.out.println("Audio를 끕니다.");
}
//setVolume() 추상 메소드의 실체 메소드
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("현재 Audio 볼륨 : " + this.volume);
}
}
package sec02;
public class RemoteControlEx {
public static void main(String[] args) {
// 아래 두줄 상수필드 선언해놨을때 상수필드 같은 경우에는
//인터페이스로 객체 생성 없이 바로 접근을 해서 사용가능
System.out.println("리모콘 최대 볼륨" + RemoteControl.MAX_VOLUME);
System.out.println("리모콘 최저 볼륨" + RemoteControl.MIN_VOLUME);
RemoteControl rc;
// rc 변수에 Television 객체를 대입
rc = new Television();
rc.turnOn();
rc.turnOff();
// rc 변수에 Audio 객체를 대입
rc = new Audio();
rc.turnOn();
rc.turnOff();
}
}
[디폴트 메소드]
▪ 인터페이스에는 완전한 실행 코드를 가진 디폴트 메소드를 선언할 수 있음
▪ 추상 메소드는 실행부(중괄호 { })가 없지만 디폴트 메소드는 실행부 있음. default 키워드가 리턴 타입 앞에 붙음
▪ 디폴트 메소드의 실행부에는 상수 필드를 읽거나 추상 메소드를 호출하는 코드를 작성할 수 있음
위의 코드에서
디폴트 메소드 추가
실행 사진 및 출력결과

출력결과
리모콘 최대 볼륨10
리모콘 최저 볼륨0
TV를 켭니다.
TV를 끕니다.
Audio를 켭니다.
Audio를 끕니다.
무음 처리합니다.
현재 Audio 볼륨 : 0
무음 해제합니다.
현재 Audio 볼륨 : 0
Audio를 켭니다.
Audio를 끕니다.
실행코드
package sec02;
public interface RemoteControl {
// 필드 -> 인터페이스에서 필드는 무조건 상수이다
// 상수라서 대문자
public static final int MAX_VOLUME = 10;
int MIN_VOLUME = 0;
// 추상 메소드
public abstract void turnOn();
void turnOff();
void setVolume(int volume);
// 디폴트 메소드
default void setMute(boolean mute) {
if(mute) {
System.out.println("무음 처리합니다");
// 추상 메소드 호출하면서 상수 필드 사용
setVolume(MAX_VOLUME);
} else {
System.out.println("무음 해제합니다.");
}
}
}
package sec02;
public class RemoteControlEx {
public static void main(String[] args) {
// 아래 두줄 상수필드 선언해놨을때 상수필드 같은 경우에는
//인터페이스로 객체 생성 없이 바로 접근을 해서 사용가능
System.out.println("리모콘 최대 볼륨" + RemoteControl.MAX_VOLUME);
System.out.println("리모콘 최저 볼륨" + RemoteControl.MIN_VOLUME);
RemoteControl rc;
// rc 변수에 Television 객체를 대입
rc = new Television();
rc.turnOn();
rc.turnOff();
// rc 변수에 Audio 객체를 대입
rc = new Audio();
rc.turnOn();
rc.turnOff();
// 디폴트 메소드를 호출할때는 구현 객체가 있어야한다
rc.setMute(true);
rc.setMute(false);
//rc 변수에 Audio 객체를 대입(교체시킴)
rc = new Audio();
rc.turnOn();
rc.turnOff();
}
}
package sec02;
public class Audio implements RemoteControl {
// 필드
private int volume;
//turnOn() 추상 메소드의 실체 메소드
public void turnOn() {
System.out.println("Audio를 켭니다.");
}
//turnOff() 추상 메소드의 실체 메소드
public void turnOff() {
System.out.println("Audio를 끕니다.");
}
//setVolume() 추상 메소드의 실체 메소드
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("현재 Audio 볼륨 : " + this.volume);
}
// 필드
private int memoryVolume;
// 디폴트 메소드 재정의
@Override
public void setMute(boolean mute) {
if(mute) {
this.memoryVolume = this.volume;
System.out.println("무음 처리합니다.");
setVolume(RemoteControl.MIN_VOLUME);
} else {
System.out.println("무음 해제합니다.");
setVolume(this.memoryVolume);
}
}
}
[정적 메소드]
▪ 구현 객체가 없어도 인터페이스만으로 호출할 수 있음
▪ 선언 시 public을 생략하더라도 자동으로 컴파일 과정에서 붙음
▪ 정적 실행부를 작성할 때 상수 필드를 제외한 추상 메소드, 디폴트 메소드, private 메소드 등을 호출할 수 없음
위의 코드에 추가한 코드
실행 사진 및 출력결과

출력결과
리모콘 최대 볼륨10
리모콘 최저 볼륨0
TV를 켭니다.
TV를 끕니다.
Audio를 켭니다.
Audio를 끕니다.
무음 처리합니다.
현재 Audio 볼륨 : 0
무음 해제합니다.
현재 Audio 볼륨 : 0
Audio를 켭니다.
Audio를 끕니다.
무음 처리합니다.
현재 Audio 볼륨 : 0
무음 해제합니다.
현재 Audio 볼륨 : 0
리모콘 건전지를 교환합니다.
실행코드
package sec02;
public interface RemoteControl {
// 필드 -> 인터페이스에서 필드는 무조건 상수이다
// 상수라서 대문자
public static final int MAX_VOLUME = 10;
int MIN_VOLUME = 0;
// 추상 메소드
public abstract void turnOn();
void turnOff();
void setVolume(int volume);
// 디폴트 메소드
default void setMute(boolean mute) {
if(mute) {
System.out.println("무음 처리합니다");
// 추상 메소드 호출하면서 상수 필드 사용
setVolume(MAX_VOLUME);
} else {
System.out.println("무음 해제합니다.");
}
}
// 정적 메소드
static void changeBattery() {
System.out.println("리모콘 건전지를 교환합니다.");
}
}
package sec02;
public class RemoteControlEx {
public static void main(String[] args) {
// 아래 두줄 상수필드 선언해놨을때 상수필드 같은 경우에는
//인터페이스로 객체 생성 없이 바로 접근을 해서 사용가능
System.out.println("리모콘 최대 볼륨" + RemoteControl.MAX_VOLUME);
System.out.println("리모콘 최저 볼륨" + RemoteControl.MIN_VOLUME);
RemoteControl rc;
// rc 변수에 Television 객체를 대입
rc = new Television();
rc.turnOn();
rc.turnOff();
// rc 변수에 Audio 객체를 대입
rc = new Audio();
rc.turnOn();
rc.turnOff();
// 디폴트 메소드를 호출할때는 구현 객체가 있어야한다
rc.setMute(true);
rc.setMute(false);
System.out.println();
//rc 변수에 Audio 객체를 대입(교체시킴)
rc = new Audio();
rc.turnOn();
rc.turnOff();
// 디폴트 메소드 호출
rc.setMute(true);
rc.setMute(false);
System.out.println();
// 정적 메소드 호출
RemoteControl.changeBattery();
}
}
[private 메소드]
▪ 인터페이스의 상수 필드, 추상 메소드, 디폴트 메소드, 정적 메소드는 모두 public 접근 제한을 가짐
public을 생략하더라도 항상 외부에서 접근이 가능
▪ 인터페이스에 외부에서 접근할 수 없는 private 메소드 선언도 가능
▪ private 메소드는 디폴트 메소드 안에서만 호출이 가능
▪ private 정적 메소드는 정적 메소드 안에서도 호출이 가능
예제 코드
실행 사진 및 출력결과

출력결과
defaultMethod1 종속 코드
defaultMethod 중복 코드A
defaultMethod 중복 코드B
defaultMethod2 종속 코드
defaultMethod 중복 코드A
defaultMethod 중복 코드B
staticMethod1 종속 코드
staticMethod 중복 코드C
staticMethod 중복 코드D
staticMethod2 종속 코드
staticMethod 중복 코드C
staticMethod 중복 코드D
실행코드
package sec02.service;
public class ServiceImpl implements Service{ // 구현 클래스
}
package sec02.service;
public interface Service {
//디폴트 메서드
default void defaultMethod1() {
System.out.println("defaultMethod1 종속 코드");
defaultCommon();
}
default void defaultMethod2() {
System.out.println("defaultMethod2 종속 코드");
defaultCommon();
}
//private 메소드
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 정적 메소드
private static void staticCommon() {
System.out.println("staticMethod 중복 코드C");
System.out.println("staticMethod 중복 코드D");
}
}
package sec02.service;
public class ServiceEx {
public static void main(String[] args) {
// 인터페이스 변수 언언과 구현 객체 대입
Service service = new ServiceImpl();
// 디폴드 메소드 호출
service.defaultMethod1();
System.out.println();
service.defaultMethod2();
System.out.println();
// service.defaultCommon(); // 불가
// 정적 메소드 호출
Service.staticMethod1();
System.out.println();
Service.staticMethod2();
System.out.println();
// service.defaultCommon(); // 불가
}
}
[다중 인터페이스]
▪ 구현 객체는 여러 개의 인터페이스를 통해 구현 객체를 사용할 수 있음
▪ 구현 클래스는 인터페이스 A와 인터페이스 B를 implements 뒤에 쉼표로 구분해서 작성해, 모든
인터페이스가 가진 추상 메소드를 재정의
아래 예제 코드 위의 코드에서 발전
실행 사진 및 출력결과

출력결과
TV를 켭니다.
TV를 끕니다.
https://www.youtube.com을 검색합니다.
실행코드
package sec02;
public interface Searchable {
// 추상 메소드
void search(String url);
}
package sec02;
public class SmartTelevision implements RemoteControl, Searchable{
private int volume;
// turnOn 추상 메소드 오버라이딩
@Override
public void turnOn() {
System.out.println("TV를 켭니다.");
}
// turnOff 추상 메소드 오버라이딩
@Override
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);
}
// search 추상 메소드 오버라이딩
@Override
public void search(String url) {
System.out.println(url + "을 검색합니다.");
}
}
package sec02;
public class MultiInterfaceImplEx {
public static void main(String[] args) {
// RemoteControl 인터페이스 선언 및 구현 객체 대입
RemoteControl rc = new SmartTelevision();
// RemoteControl 인터페이스에 선언된 추상 메소드만 호출 가능
rc.turnOn();
rc.turnOff();
// rc.search("https://www.youtube.com");
// Searchable 인터페이스 변수 선언 및 구현 객체 대입
Searchable searchable = new SmartTelevision();
// searchable 인터페이스에 선언된 추상 메소드만 호출 가능
searchable.search("https://www.youtube.com");
// searchable.turnOn();
}
}
[인터페이스 구현]
다중 인터페이스 구현 클래스
▪ 객체는 다수의 인터페이스 타입으로 사용 가능
[인터페이스 사용]
▪ 인터페이스는 필드, 매개 변수, 로컬 변수의 타입으로 선언가능
위의 코드에 더 추가
실행 사진 및 출력결과

출력결과
1)---------------------
TV를 켭니다.
TV를 끕니다.
2)---------------------
Audio를 켭니다.
현재 Audio 볼륨 : 5
3)---------------------
Audio를 켭니다.
현재 Audio 볼륨 : 5
4)---------------------
TV를 켭니다.
현재 TV 볼륨 : 5
실행코드
package sec02;
//구현 객체를 다른 클래스에서 사용 가능하다는것을 보여주는 예제
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);
}
}
package sec02;
public class MultiInterfaceImplEx {
public static void main(String[] args) {
// RemoteControl 인터페이스 선언 및 구현 객체 대입
RemoteControl rc = new SmartTelevision();
// RemoteControl 인터페이스에 선언된 추상 메소드만 호출 가능
rc.turnOn();
rc.turnOff();
// rc.search("https://www.youtube.com");
// Searchable 인터페이스 변수 선언 및 구현 객체 대입
Searchable searchable = new SmartTelevision();
// searchable 인터페이스에 선언된 추상 메소드만 호출 가능
searchable.search("https://www.youtube.com");
// searchable.turnOn();
}
}
package sec02;
public class MyClassEx {
public static void main(String[] args) {
System.out.println("1)---------------------");
Myclass myClass1 = new Myclass();
myClass1.rc.turnOn();
myClass1.rc.turnOff();
System.out.println("2)---------------------");
Myclass myClass2 = new Myclass(new Audio());
System.out.println("3)---------------------");
Myclass myClass3 = new Myclass();
myClass3.methodA();
System.out.println("4)---------------------");
Myclass myClass4 = new Myclass();
myClass4.methodB(new Television());
}
}
Quiz. SoundableExample.java (class)
SoundableExample 클래스는 아래와 같다. Soundable 인터페이스는 객체의 소리를 리턴하는
sound() 추상메서드를 갖습니다. SoundableExample의 printSound()는 Soundable 인터페이스 타입의 매개변수를 갖습니다.
아래와 같이 호출되도록 Soundable 인터페이스, Dog, Cat 클래스를 생성하시오.
public class SoundableExample {
private static void printSound(Soundable soundable) {
System.out.println(soundable.sound());
}
public static void main(String[] args) {
printSound(new Cat());
printSound(new Dog());
}
}
출력결과
야옹
멍멍
실행 사진 및 출력결과

출력결과
야옹
멍멍
실행코드
package quiz.SoundableExample;
public interface Soundable {
String sound();
}
package quiz.SoundableExample;
public class Dog implements Soundable{
@Override
public String sound() {
return "멍멍";
}
}
package quiz.SoundableExample;
public class Cat implements Soundable{
@Override
public String sound() {
return "야옹";
}
}
package quiz.SoundableExample;
public class SoundableExample{
private static void printSound(Soundable soundable) {
System.out.println(soundable.sound());
}
public static void main(String[] args) {
printSound(new Cat());
printSound(new Dog());
}
}
Quiz. Coffeeshop2 패키지
음료를 나타내는 abstract class Beverage는 아래와 같다.
// 맴버변수
private String name;
private int price;
// Beverage 생성자
public Beverage(String name) {
this.name = name;
}
// abstract 메서드
abstract void calcPrice();
// 출력메서드
public void print(int i) {
System.out.println(i + "번째 판매 음료는" + name + "이며,가격은 "
+ price);
}
Beverage클래스를 상속하는 Coffee와 Tea 클래스를 구현하시오.
각 클래스에서 생성되는 음료의 종류와 금액은 임의로 설정.
실행 클래스 CoffeeShop 클래스에는 가격을 구하고 판매정보를 출력할 수 있도록 getSalesInfo메소드를 작성하세요.
총 판매금액을 구할 수 있도록 getTotalPrice메소드를 작성하세요.
출력예시:
Quiz. Coffeeshop2 패키지
****java nara CoffeeShop영업개시****
1번째 판매 음료는Cappuccino이며,가격은 3000
2번째 판매 음료는CafeLatte이며,가격은 2500
3번째 판매 음료는ginsengTea이며,가격은 2500
4번째 판매 음료는CafeLatte이며,가격은 2500
5번째 판매 음료는redginsengTea이며,가격은 3000
총 판매 금액==>13500
Coffe의 판매 개수=>3잔
Tea의 판매 개수=>2잔
실행 사진 및 출력결과

출력결과
****java nara CoffeeShop영업개시****
1번째 판매 음료는Cappuccino이며,가격은 3000
2번째 판매 음료는CafeLatte이며,가격은 2500
3번째 판매 음료는ginsengTea이며,가격은 2500
4번째 판매 음료는CafeLatte이며,가격은 2500
5번째 판매 음료는redginsengTea이며,가격은 3000
총 판매 금액==>13500
Coffe의 판매 개수=>3잔
Tea의 판매 개수=>2잔
실행코드
package quiz.coffeeshop2;
public abstract class Beverage {
// 맴버변수
private String name;
private int price;
// Beverage 생성자
public Beverage(String name) {
this.name = name;
}
// getter setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
// abstract 메서드
abstract void calcPrice();
// 출력메서드
public void print(int i) {
System.out.println(i + "번째 판매 음료는" + name + "이며,가격은 " + price);
}
}
package quiz.coffeeshop2;
public class Tea extends Beverage {
//맴버변수
static int amount;
//Tea 생성자
public Tea(String name) {
super(name);
amount += 1;
}
//abstract메서드 오버라이딩 해서 부모클래스에 price 값 set
@Override
void calcPrice() {
if (super.getName().equals("lemonTea")) {
super.setPrice(1500);
} else if (super.getName().equals("ginsengTea")) {
super.setPrice(2500);
} else if (super.getName().equals("redginsengTea")) {
super.setPrice(3000);
}
}
}
package quiz.coffeeshop2;
public class Coffee extends Beverage {
static int amount;
//Coffee 생성자
public Coffee(String name) {
super(name);
// TODO Auto-generated constructor stub
amount += 1;
}
//abstract메서드 오버라이딩 해서 부모클래스에 price 값 set
@Override
void calcPrice() {
if (super.getName().equals("Americano")) {
super.setPrice(1500);
} else if (super.getName().equals("CafeLatte")) {
super.setPrice(2500);
} else if (super.getName().equals("Cappuccino")) {
super.setPrice(3000);
}
}
}
package quiz.coffeeshop2;
public class CoffeShop {
public static void main(String[] args) {
System.out.println("****java nara CoffeeShop영업개시****");
Beverage[] beverage = new Beverage[5];
beverage[0] = new Coffee("Cappuccino");
beverage[1] = new Coffee("CafeLatte");
beverage[2] = new Tea("ginsengTea");
beverage[3] = new Coffee("CafeLatte");
beverage[4] = new Tea("redginsengTea");
getSalesInfo(beverage);
System.out.println("총 판매 금액==>" + getTotalPrice(beverage));
System.out.println("Coffe의 판매 개수=>" + Coffee.amount + "잔");
System.out.println("Tea의 판매 개수=>" + Tea.amount + "잔");
}
// 결과와 같이 가격을 구하고 판매정보를 출력할 수 있도록 getSalesInfo메소드를 작성하세요
//음료정보 출력
static void getSalesInfo(Beverage[] beverage) {
for (int i = 0; i < beverage.length; i++) {
beverage[i].calcPrice();
beverage[i].print(i+1);
}
}
// 결과와 같이 총 판매금액을 구할 수 있도록 getTotalPrice메소드를 작성하세요.
//총 판매 금액
static int getTotalPrice(Beverage[] beverages) {
int sum = 0;
for (int i = 0; i < beverages.length; i++) {
sum += beverages[i].getPrice();
}
return sum;
}
}
추가
Quiz. Coffeeshop2 패키지_확장
출력예시
****java nara CoffeeShop영업개시****
****Coffee- Americano : 1500원 ****
****Coffee- CafeLatte : 2500원****
****Coffee- Cappuccino: 3500원****
****Tea - lemonTea : 1500원****
****Tea - ginsengTea : 2500원****
****Tea - redginsengTea:3500원****
주문할 커피메뉴의 개수는?
2
주문할 tea메뉴의 개수는?
3
5개의 메뉴를 coffee와 tea 순서대로
입력해주세요.
1번째 메뉴는?
Americano
2번째 메뉴는?
Cappuccino
3번째 메뉴는?
lemonTea
4번째 메뉴는?
ginsengTea
5번째 메뉴는?
redginsengTea
1번째 판매 음료는Americano이며,가격은 1500
2번째 판매 음료는Cappuccino이며,가격은 3000
3번째 판매 음료는lemonTea이며,가격은 1500
4번째 판매 음료는ginsengTea이며,가격은 2500
5번째 판매 음료는redginsengTea이며,가격은 3000
총 판매 금액==>11500
Coffe의 판매 개수=>2잔
Tea의 판매 개수=>3잔
'대우개발원 수업 내용 > Java 정리' 카테고리의 다른 글
| Java 개념정리 15일차 (0) | 2026.01.20 |
|---|---|
| Java 개념정리 14일차 (0) | 2026.01.19 |
| Java 개념정리 12일차 (2) | 2026.01.15 |
| Java 개념정리 11일차 (1) | 2026.01.13 |
| Java 개념정리 10일차 (1) | 2026.01.12 |