책에서는 2차원 레이아웃 라이브러리를 구현하는 과정을 통해 이번 챕터를 설명합니다.

2차원 레이아웃 라이브러리는 여러 문자열 요소를 조합해 2차원 레이아웃으로 문자열을 배치하고 표현하는 라이브러리입니다.

elem은 조합할 요소를 생성하는 팩토리 메소드 입니다. 그래서 요소끼리 above하면 세로로 요소를 결합한 새로운 요소가 생성됩니다.

beside를 수행하면 가로로 결합한 요소가 생성됩니다. 요소를 결합할 때 결합한 요소 간 길이가 맞지 않으면 양 옆에 빈 칸을 붙여서 가운데 정렬을 수행합니다.

 

클래스의 이용 형태는 시간이 지남에 따라 달라진다. 파라미터가 없는 메서드 정의를 통해 Element 클래스를 사용하는 클라리언트가 Element의 내부 구현에 영향을 받지 않는다.

네임스페이스(Namespace)는 개체를 구분할 수 있는 범위

스칼라는 메소드와 필드를 같은 개체로 인식해 추상 메소드를 서브 클래스에서 메소드가 아닌 필드로 변경할 수 있다.

 

ArrayElement에 하나의 문자열만 전달하는 ArrayElement의 서브 클래스 LineElement를 정의합니다.

 

LineElement는 한 줄의 요소를 표현하는 클래스이기 때문에 기존 heightwidth와는 다른 방식을 적용합니다.

그래서 height, width를 재정의하기 위해 widthheight 메소드를 오버라이드 합니다. 오버라이드할override 수식자를 무조건 붙어야 하는데

그 이유는 heightwidthElement 추상 클래스에서 정의한 구체 메소드이기 때문입니다.

Contents는 추상 멤버이기 때문에 ArrayElement에서 override 수식자를 붙이지 않았습니다.

자바는 오버라이드한 메소드에 대해 스칼라의 override 수식자 같이 무조건 적어줘야 하는 메타데이터 같은 게 없습니다.

물론 @Override가 존재하지만 선택사항입니다.

 

주어진 너비와 높이만큼 지정한 문자로 채우는 새로운 Element UniformElement를 정의합니다.

그래서 왼쪽과 같은 관계가 형성되고 다형성에 의해 Element 타입의 변수에는 Element의 서브 클래스 타입 객체 참조가 가능해 집니다.

 

invokeDemo 에서 Element 타입의 demo() 메소드를 호출하는 데 호출 결과 값을 보면 demo 메소드가 변수의 타입인 Element를 따라가지 않고

실행 시점의 객체 타입을 따라가는 것을 볼 수 있습니다.

 

 

상속 관계를 결정할 때는 “is-a” , 서브 클래스는 슈퍼 클래스이다. 라는 구문이 만족해야 합니다.

예를 들어 , 비둘기는 조류다. 독수리는 조류다. 라는 구문이 만족해야 합니다.

저희가 보고 있는 예제에서 현재 상속 관계가 맞는 지 살펴보겠습니다.

UniformElementElement이다.ArrayElementElement 이다. 라는 의미는 맞기 때문에 ElementUniformElement, ArrayElement 관계는 상속 관계입니다.

그러나 LineElementArrayElement 라고 할 수 없습니다. LineElement는 하나의 문자열만 표현하고 ArrayElement는 여러 문자열을 표현합니다. 비유하면 IntArray[Int]와 같습니다.

IntArray[Int]상속관계에 있지 않습니다.

그래서 오른쪽과 같이 관계를 바꿀 수 있습니다.

 

above 메소드는 위 코드와 같이 요소들을 세로로 결합한 새로운 요소를 생성하는 메소드입니다.

세로로 결합한 요소를 구현하는 방식은 contents 배열에 문자열을 추가하여 구현합니다. 그러면 객체를 print 할 때 하나의 문자열 출력하고 엔터를 치는 방식으로 세로로 결합된 요소를 만들게 됩니다.

 

beside를 수행하면 가로로 결합한 요소가 생성됩니다.

명시적으로 배열의 인덱스를 사용하는 방식보다 오류 발생 가능성이 작아집니다.

 

+ Recent posts