Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

422
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!