- 프로그램의 여러 부분이 서로 의존하는 정도를 나타내는 커플링(Coupling)을 최소화하는 것이 중요
=> 모듈화 스타일로 프로그램을 작성(프로그램을 더 작은 여러 모듈로 나눈다)
- 모듈 내부를 작업할 때는 같은 모듈을 가지고 작업하는 프로그래머와 협력
- 모듈 외부를 변경해야 하는 경우에만 다른 모듈을 가지고 작업하는 프로그래머와 협력
13.1 패키지 안에 코드 작성하기
1. package 절을 사용해 파일 전체를 패키지 안에 넣는다.
package bobsrockets.navigation class Navigator |
2. package 절 다음, 중괄호 안에 있는 정의를 모두 패키지에 넣는다.(패키징) => 한 파일 안에 여러 패키지
package bobsrockets { class Navigator |
13.2 관련 코드에 간결하게 접근하기
package bobsrockets { |
1. 어떤 클래스가 속한 패키지 안에서는 접두사가 없어도 해당 클래스에 접근할 수 있다.
2. 어떤 패키지를 포함하는 패키지 안에서는 해당 패키지에 어떤 접두어도 붙이지 않고 접근할 수 있다.
3. 패키지 밖에서 접근 가능한 모든 이름을 그 패키지 안에서도 쓸 수 있다.
중괄호를 사용하기 싫다면 아래와 같이 중첩 패키지 구현 가능(연쇄 패키지 절)
package bobsrockets package fleets class Fleet{ de addShip() = { new Ship } } |
Ex. 모든 최상위 패키지는 _root_ 패키지의 멤버로 취급
// In file lanch.scala package launch { class Booster3 } // In file bobsrockets.scala package bobsrockets { package navigation { package launch { class Booster1 } class MissionControl { val booster1 = new launch.Booster1 val booster2 = new bobsrockets.launch.Booster2 val booster3 = new _root_.launch.Booster3 } } package launch { class Booster2 } } |
13.3 임포트
: 다른 패키지의 멤버에 접근할 때 전체 경로를 명시하지 않고 간단한 이름으로 접근하게 해준다.
Ex.
package bobsdelights abstract class Fruit( val name: String, val color: String ) object Fruits { object Apple extends Fruit("apple", "red") object Orange extends Fruit("orange", "orange") object Pear extends Fruit("pear", "yellowish") val menu = List(Apple, Orange, Pear) } |
- import bobsdelights.Fruit => 자바의 싱글 타입 임포트와 같다. Fruit에 간단하게 접근
- import bobsdelights._ => 자바의 import bobsdelights.* 와 같다. bobsdelights의 모든 멤버에 간단하게 접근
- import bobsdelights.Fruits._ => Fruits의 모든 멤버에 간단하게 접근
< 자바와 다른 스칼라의 유연한 import >
- 스칼라의 임포트는 코드의 어디에라도 들어갈 수 있다.
- 임의의 값, 객체를 임포트할 수 있다.
def showFruit(fruit: Fruit) = { import fruit._ println(name + "s are " + color) } |
- 패키지 자체도 임포트 가능
import java.util.regex // 자바는 불가능하다. 자바는 java.util.regex.* 또는 java.util.regex.Pattern class AStarB { val pat = regex.Pattern.compile("a*b") } |
- 임포트 셀렉터를 통해 불러온 멤버 이름을 숨기거나 다른 이름을 지정할 수 있다.
import Fruits.{Apple, Orange} // Fruits 객체에 있는 Apple과 Orange만 불러온다. |
import Fruits.{Apple=>McIn, Orange} // Apple 객체 이름을 McIn로 바꾼다. => Apple 객체는 McIn로 참조 |
import Fruits.{Apple=>McIn, _} // Fruits의 모든 멤버를 불러오나 Apple의 이름을 McIn으로 바꾼다. |
import Fruits.{Pear => _ , _} // Fruits에서 Pear를 제외한 모든 멤버를 불러온다. |
13.4 암시적 임포트
스칼라는 모든 프로그램에 아래 임포트를 암묵적으로 추가한다.
import java.lang._ => java.lang.Thread 대신에 Thread import scala._ => 많이 사용하는 클래스 및 객체와 표준 스칼라 라이브러리, scala.List 대신에 List import Predef._ => 암시적 변환 포함, Predef.assert 대신 assert |
- 스칼라는 나중에 임포트한 패키지가 앞에서 임포트한 것을 가린다.
Ex. StringBuilder 클래스는 scala 패키지와 java.lang 패키지에 있지만 scala.StringBuilder을 가리킨다.
13.5 접근 수식자
: 스칼라는 패키지, 클래스, 객체 멤버 앞에 private와 protected 접근 수식자를 두어 멤버에 대한 접근을 제한할 수 있다.
< 비공개 멤버 >
: 자바와 유사하지만 아래와 같은 예외 존재(자바는 외부 클래스가 자신의 내부 클래스에 있는 비공개 멤버에 접근 가능)
class Outer { class Inner { private def f() = { println("f") } class InnerMost { f() // OK } } (new Inner).f() // error: f is not accessible } |
< 보호 멤버 >
: 보호 멤버를 정의한 클래스의 서브 클래스에서만 멤버 접근 가능(자바보다 엄격)
package p { class Super { protected def f() = { println("f") } } class Sub extends Super { f() } class Other { (new Super).f() // error: f is not accessible } } |
< 공개 멤버 >
: private나 protected가 없는 멤버, public 수식자 없음
< 보호 스코프 >
: private[X], protected[X] 형식
: X라는 지정자를 통해 접근이 X까지 비공개이거나 보호
: X는 패키지, 클래스, 싱글톤 객체
package bobsrockets package navigation { class LegOfJourney {
package launch { |
1. Navigator은 bobsrockets 패키지에 있는 모든 객체와 클래스에서 접근 가능 => Vehicle 객체 내부에서 접근 가능
2. distance는 Navigator 클래스 내부 어디서나 접근 가능 == 자바 내부 클래스의 비공개 멤버와 동일한 접근 제어
3. guide 는 lanuch 패키지 내부 어디서든 접근 가능
4. useStarChart는 Navigator의 모든 서브 클래스 내부와 navigation 패키지에 있는 모든 객체, 클래스에서 접근 가능
5. private[this](객체 비공개)는 그 정의를 포함하는 객체 내부에서만 접근 가능, private보다 제한
class Foo { private[this] def isFoo = true def doFoo(other: Foo) { if (other.isFoo) { // this line won't compile // ... } } } |
class Foo { private def isFoo = true def doFoo(other: Foo) { if (other.isFoo) { // this now compiles // ... } } } |
=> 같은 클래스의 다른 객체에서 접근하지 않음을 보장
< 가시성과 동반 객체 >
: 객체는 자신의 동반 클래스와 모든 접근 권리를 공유, 역도 마찬가지(클래스가 동반 객체의 비공개 멤버에 모두 접근할 수 있는 것처럼 객체도 동반 클래스의 모든 비공개 멤버에 접근할 수 있다.)
class Rocket {
|
: 싱글톤 객체는 서브 클래스를 만들 수가 없으므로 동반 객체 안에서 보호 멤버를 선언 X
< 패키지 객체 >
: 패키지 객체를 통해 패키지 내부 최상위 수준에 메소드를 정의할 수 있다. (global 메소드를 만들겠다.)
: 패키지 객체 내부에 있는 모든 정의는 패키지 자체에 속한 멤버로 취급
// In file bobsdelights/package.scala
object PrintMenu { |
: 패키지 내에서 사용할 타입 별명과 암시적 변환을 넣기 위해 패키지 객체 사용(20장, 21장)
: 패키지 객체는 package.class 라는 클래스 이름으로 컴파일
: 컴파일된 클래스 파일은 패키지 클래스와 대응하는 패키지 디렉토리에 들어간다. 이 관례를 소스 파일에도 적용하는 것이 좋다.(bobsdelights 패키지 객체의 소스코드를 bobsdelights 디렉토리에 있는 package.scala로 저장)
'스칼라' 카테고리의 다른 글
스칼라 15장 케이스 클래스와 패턴 매치(Programming in Scala, 3rd) (0) | 2019.06.02 |
---|---|
스칼라 14장 단언문과 테스트(Programming in Scala, 3rd) (0) | 2019.06.02 |
스칼라 12장 트레이트(Programming in Scala, 3rd) (0) | 2019.06.01 |
스칼라 11장 스칼라의 계층 구조(Programming in Scala, 3rd) (0) | 2019.06.01 |
스칼라 10장 상속과 구성(Programming in Scala, 3rd) (0) | 2019.06.01 |