2012-09-06 5 views
2

아래에 설명 된대로 클래스 계층 구조에서 db 저장소를 관리하는 클래스 세트가 있고 사례 클래스가 컴패니언 객체의 부모 클래스에있는 보호 된 메소드에 액세스 할 수 있기를 바랍니다 : 스칼라 : 컴패니언 객체의 부모 보호 된 메소드 사용

유일한 문제는

class TableBase[T] { 
    protected def insert(...):T {...} 
    protected def update(...) {...} 
    // Other "raw" CRUD-methods that I don't want the 
    // world to have access to 
} 

object User extends TableBase[User] { 
} 

case class User(id:Int, email:String) { 
    // But here it would be really useful to access the "raw" CRUD methods: 
    def changeEmail(newEmail:String) = User.update(...) 
} 
사용자 (클래스) TableBase에서 상속 체인에없는 때문에 User.changeEmail에 User.update에 대한 호출이 불법이라고한다

: A (편리한 있는가

method update in class TableBase cannot be accessed in object models.User 
Access to protected method update not permitted because enclosing class 
class User in package models is not a subclass of class TableBase in package 
models where target is defined 

) 이러한 유형의 호출을 허용하는 방법은 무엇입니까?

지금 changeEmail 유형의 함수를 싱글 톤으로 이동해야합니다.이 함수는 호출 코드를 다소 장황하게 만들거나 메소드 서명을 복제합니다.

+1

패키지 수준에서 [private] 또는 [protected] 메소드 선언 (http://www.artima.com/pins1ed/packages-and-imports.html#lst:access-qualifiers) 옵션 제공 ? – DaoWen

+0

이론 상으로는 그렇습니다. TableBase는 symlink-source-shared 프로젝트에 포함되어있어 다른 여러 프로젝트에서 사용하기 때문에 패키지 공간을 mangling하는 것이 엉망이됩니다. – Jxtps

답변

1

난 그냥 가능한 솔루션은 사용자 및 TableBase 사이 "가-A '관계로"입니다-A "로 전환과 같이하는 것을 깨달았다 일부 사용자 내부 TableBase의 측면,하지만 수행하여 실제로 매우 간단 여전히 가능하고 있어요 :

사실
object User { 
    private val db = new TableBase[User] { 
    // Override stuff here 
    } 
} 

, 즉 내가 원래 한 것보다 훨씬 더 나은 해결책과 (방법에 이름 충돌을 방지 즉 가질 이유가 공개 "삽입"사용자 및 그것은 좋은 h하지 h 그것이 부분적으로 보호 된 과부하를 유발합니다).

+0

나는 이것을 시험해 보았고 그 결과에 만족하지 못했다. 결국 어떤 기능이 TableBase에 들어가서 (그리고 숨겨 지는지) 무엇이 외부 적으로 액세스 가능할 것인지는 다소 임의적이었다. TableBase의 내용을 공개 할 수있게되었습니다. 보다 명확한 시나리오에서는 이것이 내가 취할 접근법입니다. – Jxtps

0

특성을 특성 CrudOps [T]로 제공하고 또 다른 특성을 보호 trait TableBase [T]에서 파생시키고 구현을 제공하고 TableBase [T]에서 singleton 개체를 파생시킵니다. 이렇게하면 TableBase는 컴파일 단위 외부에서 볼 수 없지만 클라이언트는 CrudOps [T]를 안전하게 사용할 수 있습니다.

class TableBase[T] { 
    def insert(...):T {...} 
    def update(...) {...} 
} 

object User { 
    private val db = new TableBase[User] 
} 

case class User(id:Int, email:String) { 
    def changeEmail(newEmail:String) = User.db.update(...) 
} 

나는 사용자 정의 할 수 있기를 원 :

+0

아마도 뭔가 빠졌을 것입니다. - 클라이언트가 CrudOps를 "소비"할 수 있고, 외부/호출/업데이트가 호출 가능하다면, TableBase/CrudOps의 메소드를 외부 클래스가 아닌 사용자 클래스 및 싱글 톤 내에서만 호출 가능하게하고 싶습니다. (파일이 실제로 동일한 패키지 또는 소스 파일에 있지 않음에 유의하십시오.) – Jxtps

+0

아, 알겠습니다. TableBase 특성을 패키지로 보호하기 만하면됩니다. 예를 들어, 패키지가 com.example.crud 인 경우 보호 된 [crud] TableBase [T]를 선언해야합니다. –

+0

내 [주석] (http://stackoverflow.com/questions/12291566/scala)를 참조하십시오. -using-companion-objects-parents-protected-methods/12303133 # comment16508186_12291566) TableBase 패키지 보호에 관한 질문에. – Jxtps

관련 문제