Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

424
Visualizações
¿Cómo crear una clase interna donde solo la clase externa puede acceder al constructor, pero el resto es visible en todas partes?

Originalmente quería crear una clase que pudiera abortar la creación de instancias en el constructor, pero de acuerdo con este enlace , debería usar una clase Factory. Pero ahora quiero evitar que nadie, excepto la clase de fábrica, cree un objeto de clase "Interior" mientras da acceso a los métodos de la clase interna a todos.

Ya probé esta respuesta .

 import java.util.Date object InnerFactory { class Inner private constructor(startDate: Date? = null, endDate: Date? = null) { fun getTimeDifference(): Long? { //calculates time difference but doesn't matter to this example } } fun createInnerObject(startDate: Date? = null, endDate: Date? = null): Inner? { if (startDate != null && endDate != null && !endDate.after(startDate)) { return null } return Inner(startDate, endDate) } }

Yo lo usaría como el siguiente:

 val date1 = Date(1547600000) val date2 = Date(1547600600) val inner = InnerFactory.createInnerObject(date1, date2) //should return an instance val invalidInner = InnerFactory.createInnerObject(date2, date1) //should not return an instance because the "endDate" is before "startDate" val difference = inner?.getTimeDifference()

Dice "no se puede acceder a '<init>': es privado en 'Inner'" al pasar el mouse sobre mi uso del constructor en la función "createInnerObject".

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Lo que podrías hacer:

  • introducir una interface Inner con todas las funciones necesarias que deben ser expuestas
  • haga que todas las clases sean private e implemente esa interfaz

Muestra:

 object InnerFactory { interface Inner { fun getTimeDifference(): Long? } private class InnerImpl(startDate: Date? = null, endDate: Date? = null) : Inner { override fun getTimeDifference(): Long? = TODO("some implementation") } fun createInnerObject(startDate: Date? = null, endDate: Date? = null): Inner? { if (startDate != null && endDate != null && !endDate.after(startDate)) { return null } return InnerImpl(startDate, endDate) // InnerImpl accessible from here but not from outside of InnerFactory... } }

Ahora ya no puede acceder a InnerImpl desde el exterior, pero aún tiene todas las funciones necesarias disponibles:

 // the following all work as it deals with the interface val inner = InnerFactory.createInnerObject(date1, date2) //should return an instance val invalidInner = InnerFactory.createInnerObject(date2, date1) //should not return an instance because the "endDate" is before "startDate" val difference = inner?.getTimeDifference() // the following will not compile: InnerImpl()
over 4 years ago · Santiago Trujillo Relatório

0

Desafortunadamente, los miembros private de las clases internas de Kotlin no son accesibles desde la instancia externa:

private significa visible dentro de esta clase solamente
Referencia de Kotlin /Modificadores de visibilidad

Sin embargo, Java no es tan restrictivo con sus modificadores de visibilidad:

el acceso está permitido si y solo si ocurre dentro del cuerpo del tipo de nivel superior ( §7.6 ) que encierra la declaración del miembro o constructor.
Especificación del lenguaje Java / §6 Nombres / §6.6 Control de acceso / §6.6.1 Determinación de la accesibilidad

Este es uno de los únicos casos (molestos) que he encontrado donde las reglas de Kotlin hacen imposible un patrón común de Java.

Las únicas soluciones ( si desea mantener su estructura actual) serían reescribir esta clase en Java o exponer este constructor con una visibilidad menos restrictiva (por ejemplo, internal ).

Hubo una discusión sobre esto en los foros de Kotlin: parece que se trata de una limitación de JVM y que solo funciona en Java porque el compilador genera accesores synthetic apropiados.

over 4 years ago · Santiago Trujillo Relatório

0

Podrías hacer que el constructor esté protected . De esta manera, solo lo expone a las subclases, en este caso, PrivateClass . Luego, creará una instancia de PrivateClass o null pero la devolverá como InnerClass? .

 object InnerFactory { fun createInnerObject(startDate: Date? = null, endDate: Date? = null): Inner? { // return null here if conditions are not met return PrivateClass(startDate, endDate) } open class Inner protected constructor(val startDate: Date?, val endDate: Date?) { fun getTimeDifference(): Long? { /* ... */ } } private class PrivateClass(startDate: Date?, endDate: Date?): Inner(startDate, endDate) }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda