2016-02-17 8 views
7

Mam następujące klasy Hierarchia:Dlaczego klasa publiczna nie może rozszerzyć klasy prywatnej?

interface Repository 

// This class contains some common stuff for LocalRepository and RemoteRepository. I'm never going to use this class outside this file, so I make it private 
private abstract class BasicRepositoryImpl 

// these classes are designed to be instantiated in other files  
class LocalRepository : BasicRepositoryImpl(), Repository // error 

class RemoteRepository : BasicRepositoryImpl(), Repository // error 

Ale pojawia się następujący błąd:

Subclass effective visibility 'public' should be the same or less permissive than its superclass effective visibility 'private'

nie chcę używać BasicRepositoryImpl gdziekolwiek indziej, więc to uznane private, i chcę używać LocalRepository i RemoteRepository w innych plikach tak:

class Presenter(val repo: Repository) 

val p = Presenter(LocalRepository()) 

ale zapobiega błędach mi stworzyć taką hierarchię. Czemu? Co jest z tym nie tak?

Odpowiedz

10

Klasa i jej przodkowie muszą uzyskać wszystko, co dostępne pod adresem. W przeciwnym razie byłoby to naruszenie podczas ładowania klasy przodków, a nie tylko wywoływania jej metod lub korzystania z jej funkcji. Kotlin jest bardzo czysty i jasny o tym we wszystkich przypadkach, w których dostępność jest obecna.

otwarcia go trochę pozwoliłoby rzeczy, które mogłyby spowodować naruszenie dostępu prawdziwy JVM później, jak inline funkcji w klasie publicznej, włączonych do innej klasy, nazywając prywatnej non dostępną coś przodka. Jest wiele dziur, o których nie myślisz, jeśli uważasz, że można zrobić mieszany model takiej dostępności. Macierz rozważań jest większa niż tylko chęć ukrycia niektórych klas od instancji.

Ponieważ klasa jest abstrakcyjna, nie może być używana bezpośrednio, a nie jako przodek, więc masz już pewną ochronę. Jeśli chcesz zablokować zastosowanie jako przodka poza modułem, aby jego konstruktor private lub internal i że rozwiąże ten problem:

abstract class BasicRepositoryImpl private constructor() { ... } 

Teraz masz chroniony bezpośredni instancji (abstract) lub użyć jako klasy bazowej (za pomocą abstract i prywatnych konstruktorów), więc ostatnią rzeczą do zrobienia jest nadanie mu dobrego imienia, takiego jak AbstractBaseRepository, a ludzie będą zwyczajowo zostawiać go w spokoju.

Jeśli chcesz dyskutować „dlaczego” taka jest decyzja projektowa lub ograniczenia techniczne, lub zasada ochronna ... następnie spróbuj discussion forums, cecha lub język sugestię zmiana w YouTrack. Ale uwaga: rzeczy nie są tak proste, jak się wydaje. Te zasady istnieją z powodów (, nawet jeśli inne języki niebezpiecznie zezwalają na).

0

tylko sprawiają, że klasa abstrakcyjna

Definicja: abstrakcyjna klasa to klasa, która jest zadeklarowana streszczenie-to może lub nie może zawierać metody abstrakcyjne. Klasy abstrakcyjne nie mogą być tworzone, ale mogą być poddane podklasie.

Powiązane problemy