Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

416
Vistas
¿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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda