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

Kotlin子类无法重写Java父类BaseProgressIndicator的createSpec方法及访问spec字段

解决BaseProgressIndicator子类重写createSpec方法的访问权限问题

问题场景

无法继承LinearProgressIndicator,转而用Kotlin编写AdvancedLinearProgressIndicator继承BaseProgressIndicator,但遇到两个问题:

  • 无法重写createSpec()方法,报错提示该方法无法访问父类的同名抽象方法
  • 无法访问BaseProgressIndicator的spec成员字段

报错信息

'public open fun createSpec(context: Context, attrs: AttributeSet): LinearProgressIndicatorSpec defined in AdvancedLinearProgressIndicator' has no access to 'public/package/ abstract fun createSpec(context: Context, attrs: AttributeSet): LinearProgressIndicatorSpec! defined in com.google.android.material.progressindicator.BaseProgressIndicator', so it cannot override it

核心代码片段

BaseProgressIndicator(Java核心代码)

public abstract class BaseProgressIndicator<S extends BaseProgressIndicatorSpec>
    extends ProgressBar {

   ...

  S spec;

   ...

  protected BaseProgressIndicator(
      @NonNull Context context,
      @Nullable AttributeSet attrs,
      @AttrRes final int defStyleAttr,
      @StyleRes final int defStyleRes) {
    super(wrap(context, attrs, defStyleAttr, DEF_STYLE_RES), attrs, defStyleAttr);

   ...

    spec = createSpec(context, attrs);

   ...

  }

  abstract S createSpec(@NonNull Context context, @NonNull AttributeSet attrs);

   ...

}

我的Kotlin子类代码

class AdvancedLinearProgressIndicator(
    context: Context,
    attrs: AttributeSet?,
    @AttrRes defStyleAttr: Int
) : BaseProgressIndicator<LinearProgressIndicatorSpec>(
    context,
    attrs,
    defStyleAttr,
    com.google.android.material.R.style.Widget_Material3_LinearProgressIndicator
) {

   override fun createSpec(context: Context, attrs: AttributeSet): LinearProgressIndicatorSpec {
        return LinearProgressIndicatorSpec(context, attrs)
    }
}

模拟测试代码(可正常运行)

BaseSpec.java

import android.content.Context;

public abstract class BaseSpec {

    protected BaseSpec(Context context) {

    }

    abstract void validateSpec();
}

AdvancedSpec.java

public final class AdvancedSpec extends BaseSpec {

    public AdvancedSpec(Context context) {
        super(context);
        validateSpec();
    }

    @Override
    void validateSpec() {

    }
}

Basic.java

import android.content.Context;
import android.widget.ProgressBar;

import androidx.annotation.NonNull;

public abstract class Basic<S extends BaseSpec> extends ProgressBar {
    S spec;

    protected Basic(@NonNull Context context) {
        super(context);
        spec = createSpec(context);
    }

    abstract S createSpec(@NonNull Context context);
}

Advanced.kt

import android.content.Context

class Advanced(context: Context) : Basic<AdvancedSpec>(context) {

    override fun createSpec(context: Context): AdvancedSpec {
        spec.validateSpec()
        return AdvancedSpec(context)
    }
}

解决方案

问题根源是父类BaseProgressIndicator的createSpec方法实际为包级私有访问权限(Java中未显式声明public的抽象方法默认是包可见),同时spec字段也是包级私有,而你的Kotlin子类不在同一个包下,因此无法重写方法或访问字段。

可行的解决方式:

  1. 同包继承(推荐):将AdvancedLinearProgressIndicator类移动到com.google.android.material.progressindicator包下,这是符合Material组件库封装设计的合规方案。
  2. 组合替代继承:不直接继承BaseProgressIndicator,而是通过包装LinearProgressIndicator实例的方式扩展功能,暴露需要的自定义方法。
  3. 反射访问(不推荐):通过反射强行访问spec字段,但这种方式会破坏封装性,且可能随库版本更新失效。

内容的提问来源于stack exchange,提问作者Jason Holdsworth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:17:31