Notice
Recent Posts
Recent Comments
Link
«   2026/01   »
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
Archives
Today
Total
관리 메뉴

SSinsa

8, 9장 통합 질문들 본문

Java/Java 8

8, 9장 통합 질문들

SSinsa 2019. 10. 16. 09:25

Q1.

디폴트메서드는 하위 클래스에서 구현없이 인터페이스에 이미 구현된 것을 받아서 처리한다고 한다.
이때 "여러클래스가 해당 메서드를 받아서 처리한다면 중복의 문제는 어떻게 해결가능한가?" (준우)

 

A1.

그 중복의 문제는 9장 맨 마지막에 설명되어있음.

 

Q2.

다중상속(p298) 을 설명하는데 책에서는 "디폴트 메서드를 사용하지 않아도 다중상속을 활용할 수있다고" 나와있다.

package java8.me; 

public class Main extends SuperMan implements Interface1,Interface2{ 

    public static void main(String[] args) { 
        Main main = new Main(); 
        main.SuperClass(); 
        main.A(); 
        main.B(); 
    } 

    @Override 
    public void A() { 
        System.out.println("A클래스 구현"); 
    } 

    @Override 
    public void B() { 
        System.out.println("B클래스 구현"); 

    } 
} 


코드를 구현 하였는데 디폴트메서드를 사용하지 않아도 다중상속을 할 수 있다는 말은 디폴트메서드는 다중상속을 지원한다는 말과 동일 하지 않은가?

내가 작성한 코드를 토대로 디폴트 메서드가 어떠한 방식으로 다중상속을 지원하는지 코드를 통해서 설명부탁한다.

A2. 

책에서 디폴트 메서드를 사용하지 않아도 다중 상속을 활용할 수 있다는 말은

한 인터페이스에 여러 디폴트 메서드를 추가하여 상속 받아 사용하지 않아도 

여러 인터페이스에 하나씩 넣어서 다중 상속하면 가능하다는 말

 

package java8.me; 

public class Main extends SuperMan implements Interface1,Interface2{ 

    public static void main(String[] args) { 
        Main main = new Main(); 
        main.SuperClass(); 
        main.A(); //만약 A메소드가 Interface1의 디폴트 메서드이고
        main.B(); //B메소드가 Interface2의 디폴트메서드일때
                  //아래 Main 클래스의 메소드를 구현하지 않아도 사용가능함
    } 

		

    //@Override 
    //public void A() { 
    //    System.out.println("A클래스 구현"); 
    //} 

    //@Override 
    //public void B() { 
    //    System.out.println("B클래스 구현"); 

    //} 
} 

 

Q3.

p298 - 인터페이스를 이용해 다중상속을 받을 경우 주의해야할 점은 어떤 것이 있는지 코드와 함께 설명해주시면 감사하겠습니다. (원락)

A3. 

9장 마지막에 설명하고 있음.

Q4.

p264 - 책에서는 가독성 위주로 리팩토링을 진행하고 있는데, 리팩토링이라는 것이 코드의 성능은 무시하고 가독성만 좋아지면 되는건가요? 특히 P264 - [8.1.4 명령형 데이터처리를 스트림으로 리팩토링하기]에서는 이론적으로 반복자를 이용한 기존의 모든 컬렉션 처리 코드를 스트림 API로 바꿔야 한다라고 나와있는데, 실제로 스트림 API로 바꾸었을 때 이론적 인것과 실질적인것 차이가 있는지, 있다면 어떤 점이라고 생각하는지 발표자의 생각을 적절한 예시 또는 근거를 토대로 듣고 싶습니다. (원락)

 

A4.

반복자는 사실상 어떤 경우에도 반복문 안 내용을 분석하지 않는 직관적으로 알기 어려움

예시는 매우 간단했으나 매우 길때는 스트림 API의 가독성을 따라올 수 없다고 생각함.

그러나 스트림 API는 흐름제어가 불가능 하기에 이를 잘 분석해서 스트림 API 화 해햐한다고 책에 쓰여져 있음.

따라서, 실질적으로 스트림 API로 리팩토링하기가 매우 어려운 케이스가 존재할 수 있다고 생각.

Q5.

GUI 애플리케이션에서 옵저버 패턴이 자주 등장한다고 하는데, 그 이유는 무엇인가요? (혜성)

 

 

A5.

옵저버 패턴은 관찰자가 관찰대상의 상태변화를 통지받는 패턴임

 

이런 방식으로 작동하므로 GUI에서 

이렇게 쓰여질 수 있다

방식의 특성상 GUI에서 많이 사용하는 것뿐이지 다른 곳에서 못쓰는 것은 아니다

웹이나 통신 개발에서의 예를 들면 아래 처럼 구성이 될 것이다.

MVC 패턴에서, M (model) 은 subject 역할을 맡고, V(view) 는 Observer 역할을 맡는 것도 유추 할 수 있다. 


출처 https://hamait.tistory.com/885

 

Q6.

가장 효율적으로 옵저버 패턴을 사용하려면 어떤 상황에서 사용해야 할까요? 예제와 함께 부탁드립니다.(책에서 나오는 주식과 관련된 예제 말고!) (혜성)
1번 2번 page .271


A6.

//예를 들어 온도,습도,기압 등의 기상 상태를 센서로부터 수집하는 Subject가 있다고 생각하고, 
//해당 Subject는 기상 상태의 변화가 있을때, Observer들에게 변화를 알리고 Observer들은 
//기상 상태 변화에 따른 새로운 데이터를 디스플레이에 출력하는 것을 구현하는 상황이다.

 
public class Subject extends Observable{ //Observable API
    
    private int temp;
    
    public void changeTemp(int temp) {
        setChanged();
        notifyObservers(temp);
    }
    
    public void changeTemp() {
        setChanged();
        notifyObservers();
    }
    
    public void setChangeTemp(int temp) {
        this.temp = temp;
        changeTemp(temp);
    }
 
    public int getTemp() {
        return temp;
    }
 
    public void setTemp(int temp) {
        this.temp = temp;
        changeTemp();
    }
    
}



public class Observer1 implements Observer { 
    
    private Observable sub;
    private int temp;
    
    public Observer1(Observable sub) {
        this.sub=sub;
        sub.addObserver(this);
    }
 
    @Override //update만 오버라이드
    public void update(Observable o, Object arg) {
        if(o instanceof Subject) {
            if(arg != null) this.temp=(int)arg;
            else this.temp=((Subject) o).getTemp();
        }
        
        display();
 
    }
    
    public void display() {
        System.out.println("Observer1 - "+temp);
    }
 
}
 
public class Observer2 implements Observer {
    
    private Observable sub;
    private int temp;
    
    public Observer2(Observable sub) {
        this.sub=sub;
        sub.addObserver(this);
    }
 
    @Override //update만 오버라이드
    public void update(Observable o, Object arg) {
        if(o instanceof Subject) {
            if(arg != null) this.temp=(int)arg;
            else this.temp=((Subject) o).getTemp();
        }
        display();
    }
 
    public void display() {
        System.out.println("Observer2 - "+temp);
    }
    
}


public class ObserverMain {
 
    public static void main(String[] args) {
        
        Subject sub= new Subject();
        
        Observer observer1 = new Observer1(sub);
        Observer observer2 = new Observer2(sub);
        
        sub.changeTemp(20);
        sub.setTemp(10);
    }
 
}

 

결과

Observer2 - 20

Observer1 - 20

Observer2 - 10

Observer1 - 10

 

 

출처: https://coding-start.tistory.com/246 [코딩스타트]

 

결과적으로 Observer 구현체들의 어떠한 메소드도 호출하지 않았음에도 불구하고 Subject 클래스의 상태가 바뀔 때마다 Observer의 메소드가 호출되어 동작한다. 이러한 패턴이 옵저버 패턴이다.

 

Q7.

295p 추상클래스와 인터페이스 중 두번째 항목, 추상클래스는 인스턴스변수로 공통상태를 가질 수 있지만 인터페이스는 인스턴스변수를 가질 수 없다가 무슨말? (상훈)

 

A7.

인터페이스는 인스턴스 변수를 못만든다는 것 즉 , final, abstract 로만 가능 (자동변환됨)

//추상메서드

abstract class SmartPhone {
	String call = "전화";
	String sns = "SNS";
	String search = "인터넷 검색";
	String game = "게임";
	String company, name, color, size, weight, price;
	public void purpose() { // 일반 메소드
		System.out.println("사용목적 : " + call + " / " + sns + " / " + search + " / " + game);
	}

	abstract public void spec(); // 추상 메소드 : 오버라이딩 필수!
}

//인터페이스

public interface A {
  // 1) 규칙이기 때문에 무조건 공개 메서드이고 추상 메서드이다.
  public abstract void m1();
 
  // 2) public을 생략해도 내부적으로 public으로 간주한다.
  abstract void m2();
 
  // 3) abstract를 생략해도 내부적으로 abstract로 간주한다.
  void m3();
 
  // 4) 절대 구현 메서드를 가질 수 없다.
  // void m4() {} // 컴파일 오류!

  // [필드 선언 규칙]
  // 1) 규칙이기 때문에 무조건 공개 필드이고, 스태틱 필드이다
  //    그리고 값을 바꿀 수 없는 상수 필드이다.
 
  public static final int v1 = 200;
 
  // 2) public을 생략하면 내부적으로 public으로 간주한다.
  static final int v2 = 200;
 
  // 3) static을 새약하면 내부적으로 static으로 간주한다.
  final int v3 = 200;
 
  // 4) final을 생략하면 내부적으로 final로 간주한다.
  int v4 = 200;
}

 

Q8.

264p 맨 아래 명령형 코드를 스트림 api로 바꾸도록 돕는 도구의 대표적인 케이스 2개 정도 부탁 (상훈)

 

 

A8.

LambdaFicator 가 있다. 람다찬양 툴이라고 얼핏 본것 같은데

svn 소스 머지 할때 처럼 제공하는 방법인듯하다

아래 영어 논문 참고...

 

http://dig.cs.illinois.edu/papers/icse13tool-LambdaFicator.pdf

'Java > Java 8' 카테고리의 다른 글

Chapter 09. 디폴트 메소드  (0) 2019.10.16