인터페이스
- 인터페이스의 역할
다형성 구현
개발 코드와 객체의 통신 접점 => 개발 코드가 인터페이스 메소드 호출, 인터페이스는 객체 메소드 호출 (접점일 뿐 실제 구현은 개발자가)
여러 객체들과 사용 가능 => 코드 변경 없이 객체 변경 => 실행 내용, 리턴값 다양화
.class로 저장됨 => 클래스와 동일 이름 불가
다중 구현 가능
public 접근 제한 => 다른 패키지에서도 사용 가능하도록
- 인터페이스 선언
인스턴스필드 불가
생성자 불가 (인터페이스는 객체로 생성 불가하므로)
상수, 메소드만 가능
멤버: 상수 필드, ☆추상 메소드☆ (+디폴트 메소드, 정적 메소드)
- 인터페이스 멤버
상수 필드 : 상수 선언 시 초기값 반드시 대입
추상 메소드 : 실제 실행부는 구현 객체가 가짐
디폴트 메소드 : 인스턴스 메소드와 유사 기능
정적 메소드 : 객체 없이 인터페이스만으로 호출
- 상수, 메소드 선언
상수 필드 : public, static, final 생략해도 자동적으로 컴파일 과정에서 붙음
ex. public int MAX = 10;
추상 메소드 : 중괄호 X, public abstract 생략해도 자동적으로 "
ex. public void turnOn();
디폴트 메소드 : public 생략해도 자동적으로 " , 메소드에 실행 내용도 작성
ex. default void setMute(boolean mute){if(mute)~}
정적 메소드 : public 생략해도 자동적으로 "
ex. static void change(){sysout~}
- 인터페이스 구현
1. 구현 클래스
public class 구현클래스명 implements 인터페이스명{
...
추상 메소드의 실체 메소드 선언
...
}
=> 인터페이스의 모든 메소드 => public => public보다 낮은 접근 제한 불가
=> 예제 클래스
인터페이스 변수 = 구현 객체;
ex. Television tv = new Television(); => Television 객체 -> 선언한 인터페이스 변수에 대입
or
인터페이스 변수;
변수=구현객체;
ex. RemoteControl rc;
rc = new Television();
=> 변수 선언 후 변수에 구현 객체 대입
2. 익명 구현 객체
단기 이벤트, 임시 작업 시 사용
추상메소드의 실체 메소드 작성 필수
추가 필드, 메소드 선언 가능하지만 익명 객체 안에서만 사용 가능, 인터페이스 변수로 접근 불가
인터페이스 변수 = new 인터페이스(){실체 메소드};
ex. remoteControl rc = new RemoteControl(){~~};
3. 다중 구현 클래스
public 구현 클래스명 implements 인터페이스1, 인터페이스2 {
인터페이스1 추상메소드의 실체메소드 선언
인터페이스2 추상메소드의 실체메소드 선언
}
- 다중 구현
|
1
2
3
4
5
|
public interface Searchable {
void search(String url);
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public class SmartTV implements RemoteControl, Searchable{ //다중구현
private int volume;
@Override
public void search(String url) {
System.out.println(url+"을 검색합니다.");
}
@Override
public void turnOn() {
System.out.println("스마트TV를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("스마트TV를 끕니다.");
}
@Override
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);
}
}
|
cs |
- 인터페이스 사용 (예제에서)
1. 추상 메소드
RemoteControl rc = new Television();
rc. turnOn();
rc.turnOff();
2. 디폴트 메소드 : 구현 클래스에서 재정의(필요 시) 후 예제에서 사용
RemoteControl rc = new Television();
rc.setMute(true);
3. 정적 메소드 : 인터페이스로 바로 호출 가능
RemoteControl.change();
- RemoteControl 인터페이스
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public interface RemoteControl {
//상수
public final int MAX_VOLUME=10; //필드 생성 불가 => static final 생략해도 상수로 자동 생성
public final int MIN_VOLUME=0;
//추상 메소드: 객체의 메소드 설명, 실제 실행부는 객체가 가짐
public void turnOn(); //컴파일시 자동으로 abstract로 인식 (생략 ok)
public void turnOff();
public void setVolume(int volume);
//디폴트 메소드: 객체 구현과 관련 X 인스턴스 메소드
default void setMute(boolean mute) {
if (mute) {
System.out.println("무음 처리합니다");
}else {
System.out.println("무음 해체합니다");
}
}
//정적 메소드: 인터페이스 자체에서 수행되는 메소드
static void changeBattery() {
System.out.println("건전지를 교환합니다");
}
}
|
cs |
- 구현 클래스
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class Television implements RemoteControl{ //추상메소드 구현 필=>add unimplemented methods
private int volume;
@Override
public void turnOn() {
System.out.println("TV를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("TV를 끕니다.");
}
@Override
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);
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class Audio implements RemoteControl {
private int volume;
@Override
public void turnOn() {
System.out.println("오디오를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("오디오를 끕니다.");
}
@Override
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("현재 오디오 볼륨 : "+this.volume);
}
}
|
cs |
- 인터페이스 사용 예제
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class RemoteControlEx1 {
public static void main(String[] args) {
RemoteControl rc;
rc=new Television(); //다형성
rc.turnOn();
rc.setVolume(5);
rc.setMute(true);
rc.setMute(false);
rc.turnOff();
rc=new Audio(); //다형성
rc.turnOn();
rc.setVolume(20);
rc.setMute(true);
rc.setMute(false);
rc.turnOff();
}
}
|
cs |
- vehicle 클래스 -> 인터페이스
|
1
2
3
4
|
public interface Vehicle {
//메서드
public void run();
}
|
cs |
|
1
2
3
4
5
6
|
public class Taxi implements Vehicle {
@Override
public void run() {
System.out.println("택시가 달립니다.");
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
|
public class Bus implements Vehicle {
@Override
public void run() {
System.out.println("버스가 달립니다.");
}
public void checkFare() {
System.out.println("승차요금을 체크합니다.");
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
|
public class VehicleEx2 {
public static void main(String[] args) {
Vehicle vehicle = new Bus(); //자동타입변환
vehicle.run(); //오버라이드한 run 실행
Bus bus=(Bus)vehicle; //강제형변환
bus.run();
bus.checkFare();
}
}
|
cs |
//
버스가 달립니다.
버스가 달립니다.
승차요금을 체크합니다.
- 매개변수의 다형성
|
1
2
3
4
5
6
7
8
|
public class Driver {
void Drive(Vehicle vehicle) {
Bus bus=(Bus)vehicle;
bus.checkFare();
vehicle.run();
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
|
public class DriverEx1 {
public static void main(String[] args) {
Driver chulsu = new Driver();
Taxi taxi = new Taxi();
Truck truck = new Truck();
Bus bus = new Bus();
chulsu.Drive(bus);
}
}
|
cs |
//
승차요금을 체크합니다.
버스가 달립니다.
|
1
2
3
4
5
6
7
8
9
10
11
|
public class DriverEx1 {
public static void main(String[] args) {
Driver chulsu = new Driver();
Taxi taxi = new Taxi();
Truck truck = new Truck();
Bus bus = new Bus();
chulsu.Drive(bus);
}
}
|
cs |
=> 해결
|
1
2
3
4
5
6
7
8
9
10
|
public class Driver {
//메소드
void Drive(Vehicle vehicle) {
if (vehicle instanceof Bus) { //Bus 객체가 Vehicle 인터페이스타입으로 변환된 건지 확인
Bus bus=(Bus)vehicle; //강제형변환
bus.checkFare(); //강제형변환 전에는 불가능
}
vehicle.run();
}
}
|
cs |
=> 강제 형변환: 구현 객체가 인터페이스 타입으로 변환돼있는 상태에서 가능 (객체->인터페이스->객체)
- 인터페이스 배열
public class Car {
Tire[] tires = {
new HankookTire{},
new HankookTire{},
new HankookTire{},
new HankookTire{},
};
void run(){
for (Tire tire : tires){
tire.roll();
}
}
}
public class CarEx{
public main~ {
Car myCar = new Car();
myCar.run();
myCar.tires[0] = new KumhoTire;
myCar.tires[1] = new KumhoTire;
myCar.run();
}
}
//
한국타이어
한국타이어
한국타이어
한국타이어
금호타이어
금호타이어
한국타이어
한국타이어
- 다중 상속 받는 인터페이스 => 추상 클래스여서 가능
public interface Vehicle extends iAnimal, RemoteControl{
public void run();
}
- 디폴트 메소드 있는 인터페이스 상속
1. 단순 상속
2. 재정의(오버라이드)해 실행내용 변경
3. 디폴트메소드를 추상메소드로 재선언
8장 확인문제
구현 객체는 인터페이스 타입으로 자동 변환
구현 클래스가 추상메소드의 실체메소드 갖지 않으면 추상클래스가 됨
배열이 인터페이스 타입 => 다양한 구현 객체 저장 가능
- 3번 문제
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public interface Soundable {
String sound(); //추상메소드
}
public class Cat implements Soundable {
@Override
public String sound() {
return "야옹";
}
}
public class Dog implements Soundable {
@Override
public String sound() {
return "멍멍";
}
}
public class Soundable Example{
public static void main(String[] args) { //메인메소드 순서 상관 X 무조건 메인 먼저 호출함
printSound(new Cat());
printSound(new Dog());
}
private static void printSound(Soundable soundable) {
System.out.println(soundable.sound());
}
}
|
cs |
다른 방법
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class SoundableEx1 {
public static void main(String[] args) {
Soundable sa;
sa=new Cat();
printSound(sa);
sa=new Dog();
printSound(sa);
}
private static void printSound(Soundable soundable) {
System.out.println(soundable.sound());
}
}
|
cs |
- 4번 문제
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
public interface DataAccessObject {
void select();
void insert();
void update();
void delete();
}
public class OracleDao implements DataAccessObject{
@Override
public void select() {
System.out.println("Oracle DB에서 검색");
}
@Override
public void insert() {
System.out.println("Oracle DB에 삽입");
}
@Override
public void update() {
System.out.println("Oracle DB를 수정");
}
@Override
public void delete() {
System.out.println("Oracle DB에서 삭제");
}
}
public class DaoEx1 {
public static void dbWork(DataAccessObject dao) {
dao.select();
dao.insert();
dao.update();
dao.delete();
}
public static void main(String[] args) {
dbWork(new OracleDao());
dbWork(new MySqlDao());
}
}
|
cs |
//
Oracle DB에서 검색
Oracle DB에 삽입
Oracle DB를 수정
Oracle DB에서 삭제
MySql에서 검색
MySql에 삽입
MySql를 수정
MySql에서 삭제
- 5번 문제
public interface Action { void work(); }
|
1
2
3
4
5
6
7
8
9
10
11
|
public class ActionEx1 {
public static void main(String[] args) {
Action action = new Action() { //익명으로
public void work() {
System.out.println("복사를 합니다.");
}
};
action.work();
}
}
|
cs |
//
복사를 합니다
중첩 클래스, 중첩 인터페이스
- 정의
중첩 클래스 : 클래스 내부에 선언되는 클래스
중첩 인터페이스 : 클래스 내부에 선언되는 인터페이스
- 중첩 클래스
| 인스턴스 멤버 클래스 | class A { class B{..} } |
A 객체 생성해야만 사용 가능 |
| 정적 멤버 클래스 | class A { static class B{..} } |
A클래스로 바로 접근 가능 |
| 로컬 클래스 | class A { void method(){ class B{..} } } |
method()가 실행해야만 사용 가능 |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
public class ClassA {
//클래스A 필드
int fieldA;
//클래스A 생성자
public ClassA() {
System.out.println("ClassA가 생성됨");
}
//클래스A 메서드
void methodA() {
//로컬 클래스 (외부클래스 메소드 내 클래스)
class ClassD {
//필드
int fieldD;
//생성자
public ClassD() {
System.out.println("메서드 안에 있는 로컬클래스 ClassD가 생성됨");
}
//메서드
void methodD() {}
}
}
//인스턴스 내부 클래스 => 인스턴스 필드, 메서드만 선언 가능
class ClassB{
//클래스B 필드
int fieldB;
//static int fieldB2;
//클래스B 생성자
public ClassB() {
System.out.println("ClassB가 생성됨");
}
//클래스B 메서드
void methodB() {}
}
//정적 내부 클래스 => 모든 종류 필드, 메서드 선언 가능
static class ClassC{
int fieldC;
static int fieldC2;
public ClassC() {
System.out.println("ClassC가 생성됨");
}
void methodC() {}
static void methodC2() {}
}
}
|
cs |
- 내부 인스턴스 클래스
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class NestedClassEx1 {
public static void main(String[] args) {
ClassA a = new ClassA(); //인스턴스 ClassA 객체 생성
a.fieldA=30;
a.methodA();
//ClassA의 내부클래스 생성(반드시 외부 클래스 생성된 후)
ClassA.ClassB b = a.new ClassB(); //인스턴스 ClassB 객체 생성
b.fieldB=50;
b.methodB();
}
}
|
cs |
- 내부 정적 클래스
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class NestedClassEx2 {
public static void main(String[] args) {
//내부 정적 클래스 객체 생성 => 외부클래스 객체 필요 X
ClassA.ClassC c = new ClassA.ClassC();
c.fieldC=30; //인스턴스 필드, 메소드
c.methodC();
ClassA.ClassC.fieldC2=50; //정적 필드, 메소드 => ClassA.~
ClassA.ClassC.methodC2();
}
}
|
cs |
- 로컬 클래스 : 외부클래스 메소드 안에서만 생성, 사용 가능
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
public class ClassA {
//클래스A 필드
int fieldA;
//클래스A 생성자
public ClassA() {
System.out.println("ClassA가 생성됨");
}
//클래스A 메서드
void methodA() {
//로컬 클래스 (외부클래스 메소드 내 클래스)
class ClassD {
//필드
int fieldD;
//생성자
public ClassD() {
System.out.println("메서드 안에 있는 로컬클래스 ClassD가 생성됨");
}
//메서드
void methodD() {}
}
ClassD d = new ClassD();
d.fieldD=60;
d.methodD();
}
//인스턴스 내부 클래스 => 인스턴스 필드, 메서드만
class ClassB{
//클래스B 필드
int fieldB;
//static int fieldB2;
//클래스B 생성자
public ClassB() {
System.out.println("ClassB가 생성됨");
}
//클래스B 메서드
void methodB() {}
}
//정적 내부 클래스 => 인스턴스 필드, 메서드도 생성 가능
static class ClassC{
int fieldC;
static int fieldC2;
public ClassC() {
System.out.println("ClassC가 생성됨");
}
void methodC() {}
static void methodC2() {}
}
}
|
cs |
- 멤버 클래스 사용 제한
인스턴스 멤버 클래스 : 외부 클래스의 모든 필드, 메소드 접근 가능
정적 멤버 클래스 : 외부 클래스의 정적 필드, 메소드에만 접근 가능
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
public class ClassA {
//클래스A 필드
int fieldA;
//클래스A 생성자
public ClassA() {
System.out.println("ClassA가 생성됨");
}
//클래스A 메서드
void methodA() {
//로컬 클래스 (외부클래스 메소드 내 클래스)
class ClassD {
//필드
int fieldD;
//생성자
public ClassD() {
System.out.println("메서드 안에 있는 로컬클래스 ClassD가 생성됨");
}
//메서드
void methodD() {}
}
ClassD d = new ClassD();
d.fieldD=60;
d.methodD();
}
//인스턴스 내부 클래스
class ClassB{
//클래스B 필드
int fieldB;
//static int fieldB2;
//클래스B 생성자
public ClassB() {
System.out.println("ClassB가 생성됨");
}
//클래스B 메서드
void methodB() {
fieldA=10;
methodA();
}
}
//정적 내부 클래스
static class ClassC{
int fieldC;
static int fieldC2;
public ClassC() {
System.out.println("ClassC가 생성됨");
}
void methodC() {
//fieldA=10; //정적 내부 클래스=> 외부클래스 인스턴스 메소드, 필드 사용 불가
}
static void methodC2() {}
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
public class ClassA {
//클래스A 필드
int fieldA;
static int fieldA2;
//클래스A 생성자
public ClassA() {
System.out.println("ClassA가 생성됨");
}
//클래스A 메서드
void methodA() {
//로컬 클래스 (외부클래스 메소드 내 클래스)
class ClassD {
//필드
int fieldD;
//생성자
public ClassD() {
System.out.println("메서드 안에 있는 로컬클래스 ClassD가 생성됨");
}
//메서드
void methodD() {}
}
ClassD d = new ClassD();
d.fieldD=60;
d.methodD();
}
//인스턴스 내부 클래스 => 인스턴스 필드, 메서드만
class ClassB{
//클래스B 필드
int fieldB;
//static int fieldB2;
//클래스B 생성자
public ClassB() {
System.out.println("ClassB가 생성됨");
}
//클래스B 메서드
void methodB(int fieldB) {
this.fieldB=fieldB;
fieldA=10;
methodA();
}
}
//정적 내부 클래스 => 인스턴스 필드, 메서드도 생성 가능
static class ClassC{
int fieldC;
static int fieldC2;
public ClassC() {
System.out.println("ClassC가 생성됨");
}
void methodC() {
fieldA2=10;
}
static void methodC2() {}
}
}
|
cs |
- 중첩 인터페이스
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
public class Button {
//인터페이스 타입 필드
OnClickListener listener;
//메서드(매개변수의 다형성)
void setOnClickListener(OnClickListener listener) { //매개변수로 인터페이스 받음
this.listener=listener;
}
//메서드
void touch() {
listener.onClick();
}
//중첩 인터페이스
interface OnClickListener{
void onClick(); //추상메소드
}
}
//구현 클래스
public class CallListener implements Button.OnClickListener{
@Override
public void onClick() {
System.out.println("전화를 겁니다");
}
}
//구현 클래스
public class MessageListener implements Button.OnClickListener{
@Override
public void onClick() {
System.out.println("문자를 합니다");
}
}
public class ButtonEx1 {
public static void main(String[] args) {
Button btn = new Button(); //인스턴스 객체 생성
// CallListener call = new CallListener();
btn.setOnClickListener(new CallListener());
//익명으로 인터페이스 구현 => 오버라이딩한 메소드 구현 btn.touch();
btn.setOnClickListener(new MessageListener());
btn.touch();
}
}
|
cs |
//
전화를 겁니다
문자를 합니다
- 익명 구현 객체
- 필드에 구현 객체 대입
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
public class Person {
//메서드
void wake() {
System.out.println("7시에 일어납니다");
}
}
public class Anonymous {
//필드값으로 클래스 대입 //타 클래스를 필드로 선언 //필드가 객체를 받음
Person pField=new Person() {
//타입: Person, 필드명: pField, 중괄호 안: 필드값 ex. int balance=20;
void work() {
System.out.println("출근합니다");
}
@Override
void wake() {
System.out.println("6시에 일어납니다");
work();
}
};//pField
//메서드
void method1(Person pField) {
pField.wake();
}
}
public class AnonymousEx1 {
public static void main(String[] args) {
Anonymous anon = new Anonymous(); //인스턴스 객체 생성
anon.pField.wake();
anon.method1(new Person() {
void study() {
System.out.println("공부합니다");
}
@Override
void wake() {
System.out.println("8시에 일어납니다");
study();
}
});
}
}
|
cs |
//
6시에 일어납니다
출근합니다
8시에 일어납니다
공부합니다
- 로컬 변수에 구현 객체 대입
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
public class Anonymous {
Person pField=new Person() {
void walk() {
System.out.println("산책합니다");
}
@Override
void wake() {
System.out.println("6시에 일어납니다");
walk();
}
};//pField
//메서드
void method1(Person person) {
person.wake();
}
//메서드
void method2() {
//로컬변수로 객체 대입
Person localPerson = new Person() {
void study() {
System.out.println("공부합니다");
}
void wake() {
System.out.println("7시에 일어납니다");
study();
}
};
//로컬변수 사용
localPerson.wake();
}
}
public class AnonymousEx1 {
public static void main(String[] args) {
Anonymous anon = new Anonymous(); //인스턴스 객체 생성
anon.pField.wake(); //필드 대입
anon.method1(new Person() { //메소드 대입
void work() {
System.out.println("출근합니다");
}
@Override
void wake() {
System.out.println("8시에 일어납니다");
work();
}
});
anon.method2(); //로컬변수 대입
}
}
|
cs |
//
6시에 일어납니다
산책합니다
8시에 일어납니다
출근합니다
7시에 일어납니다
공부합니다