You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 15:05:33