如何在Kotlin中实现仅父类可访问的私有嵌套类?
Kotlin私有嵌套类的访问控制问题
编辑:文末提供了该问题的Java实现代码
我想在Kotlin中创建一个私有嵌套类,使其仅能被父类访问,其他任何地方都无法直接访问。
以下代码片段中,我用//(!)标记了出现编译错误的行:
class Sphere(val radius: Double = 1.toDouble()) { var pointsLinkedHashSet: LinkedHashSet<Point> = linkedSetOf() //(!)'public' property exposes its 'private-in-class' type argument Point (make "Point" public) fun getPoints(): LinkedHashSet<Point> { return pointsLinkedHashSet } //(!) 'public' function exposes its 'private-in-class' type argument Point (make "Point" public) fun getLastPoint(): Point = pointsLinkedHashSet.last() //(!) 同上错误 fun clearPoints() = pointsLinkedHashSet.clear() fun addPoint(radius: Double = this.radius, latitude: Double, longitude: Double): Point { val point = Point(radius, latitude, longitude) pointsLinkedHashSet.add(point) return point } //(!) 同上错误 private class Point( val radius: Double, val latitude: Double, val longitude: Double ) }
对应的Main类代码如下:
class Main { companion object { @JvmStatic fun main(args: Array<String>) { val sphere = Sphere() val point = sphere.addPoint(10.toDouble(), 10.toDouble(), 10.toDouble()) // 这行正常工作 val point1 = sphere.getLastPoint() // 这行也正常 val point2 = Sphere.Point(10.toDouble(), 10.toDouble(), 10.toDouble()) // 这行无法运行,因为Point是私有类,符合预期 val radius = point.radius // 下面三行同理可访问属性 val latitude = point.latitude val longitude = point.longitude } } }
我已经在代码注释里描述了期望的行为:外部可以通过Sphere的方法获取Point实例,但不能直接创建Point对象,同时能访问Point的属性。
这个逻辑在Java里很容易实现,但我还没找到Kotlin里的实现方式,也没搜到相关文章,尽管这是个常见问题。
是不是我忽略了什么关键点?恳请帮忙解决,谢谢。
更新:附Java实现代码
Sphere类
package org.example; import java.util.LinkedHashSet; public class Sphere { private final Double radius; private final LinkedHashSet<Point> pointsLinkedHashSet = new LinkedHashSet<Point>(); public Double getRadius() { return this.radius; } public Sphere(Double radius) { this.radius = radius; } public Point getLastPoint() { if (pointsLinkedHashSet.isEmpty()) return null; return (Point) pointsLinkedHashSet.toArray()[pointsLinkedHashSet.size() - 1]; } public Point addPoint(Double latitude, Double longitude) { Point point = new Point(latitude, longitude); pointsLinkedHashSet.add(point); return point; } class Point { private final Double radius; private final Double latitude; private final Double longitude; Double getLatitude() { return latitude; } Double getLongitude() { return longitude; } Double getRadius() { return this.radius; } private Point(Double latitude, Double longitude) { this.radius = Sphere.this.radius; this.latitude = latitude; this.longitude = longitude; } } }
Main类
package org.example; public class Main { public static void main(String[] args) { Sphere sphere = new Sphere(1.0); System.out.println("Sphere radius = " + sphere.getRadius()); Sphere.Point point = sphere.addPoint(10.0,10.0); System.out.println("Point radius = " + point.getRadius()); System.out.println("Point latitude = " + point.getLatitude()); System.out.println("Point longitude = " + point.getLongitude()); // Sphere.Point point = new Sphere.Point(10.0,10.0); 无法运行 // 不能直接创建Point对象,因为构造方法是私有的,这正是期望的行为! Sphere.Point point1 = sphere.getLastPoint(); System.out.println("Point1 radius = " + point1.getRadius()); System.out.println("Point1 latitude = " + point1.getLatitude()); System.out.println("Point1 longitude = " + point1.getLongitude()); } }
输出结果
Sphere radius = 1.0 Point radius = 1.0 Point latitude = 10.0 Point longitude = 10.0 Point1 radius = 1.0 Point1 latitude = 10.0 Point1 longitude = 10.0
内容的提问来源于stack exchange,提问作者Tim Korelov
相关产品推荐
相关产品推荐

