デフォルトのゲッターを持つ多くの不変のプロパティを提供するインターフェイスがあるとします
interface Repository {
val name : String
val pattern : String
get() = "foo/bar/baz"
var url : String
get() = "http://mycompanyrepo.com/$name"
fun add() {
TODO("do something interesting here")
}
}
現在、デフォルトのほとんどを使用する具体的な実装がいくつかあります。ただし、
ConfigurableRepository
も提供したいこれにより、他のユーザーパラメーターに基づいて、実行時にこれを構成する他のプロジェクトの柔軟性が高まります。
オプションのパラメーターを持つプライマリコンストラクターを作成するにはどうすればよいですか?
私は次のものに沿って何かを望んでいました:
class ConfigurableRepo(var name, var pattern, var url) {
...
}
明確化のために編集
ここでの目的は、名前付きパラメーターがオプションであるプライマリコンストラクターの動作を使用することです。より具体的には、
name
、
pattern
、および
url
コンストラクターを呼び出す人はすべてオプションであり、デフォルトでインターフェースのゲッターになります。しかし、私は明らかにKotlin
interface
を強制しようとしていますこのモデルに合わせると、おそらく私は最終的にここでスーパーにアクセスできないので、おそらくnoob Kotlinユーザーの間違いです。
からクラスのドキュメント
In fact, for declaring properties and initializing them from the primary constructor, Kotlin has a concise syntax:
class Person(val firstName: String, val lastName: String, var age: Int) {
// ...
}
私はこれがスーパータイプのメンバーを隠し、
override
を必要とするというエラーを受け取っているようです修飾子。スーパータイプをオーバーライドしてからデフォルトを提供しようとすると、このコンテキストではスーパータイプにアクセスできないと文句を言います。
これは、mutableのセカンダリコンストラクターでのみ実行できますか 値?
また、従来の設定をサポートするインターフェースを提供するためのより良い方法についての提案/フィードバックも受け付けています。最も重要な側面は、インターフェイスが常に規則のデフォルトを提供することです。または、もっと簡単に言えば:
もっと良い方法はありますか?
次のような抽象クラスを使用します。
abstract class Repository { open val name = "default" open val pattern = "default" open val url = "default" } // example: only override name class RepoWithDifferentName( override val name: String ): Repository() { // ... }
var
でそれを行う方法を見つけたので s、ここにあなたの質問からの正確なインターフェースの答えがあります。class ConfigurableRepo( private var _name: String, private var _pattern: String, private var _url: String) : Repository { override val name get () = _name override val pattern get () = _pattern override var url get () = _url set (u: String) { _url = u } }
次のようなデフォルトコンストラクターのパラメーターにデフォルト値を設定する場合(擬似コード、コンパイルしない):
class ConfigurableRepo( override var name, override var pattern = super.pattern, override var url = super.url ) { ... }
次に、目的のデフォルト値をメソッド宣言で表現できない場合に常に使用できる「null as default pattern」を使用します。あなたの場合、次のようになります:
class ConfigurableRepo ( override val name: String, _url: String? = null, _pattern: String? = null ): Repository { override val pattern = _pattern ?: super.pattern override var url = _url ?: super.url // ... more code ... }
ご覧のとおり、このトリックは
val
で動作します 同様にvar
プロパティとフィールド。プロパティname
インターフェイスにデフォルト値を持たないものは、このクラスの単純なフィールドで実装されます。
関連記事
- Puppetのデフォルト値を持つ複雑な構造
- typescriptでプロトタイプを拡張するときにデフォルトのパラメータ値を使用するにはどうすればよいですか?
- cloud initconfigを使用して/ etc/ssh/sshd_configのデフォルト値を変更する
- cloud initconfigを使用して/ etc/ssh/sshd_configのデフォルト値を変更する
- ラジオボタンに基づくMatselectのデフォルト値
- JavaScriptコンストラクター関数は値を未定義として返します
- Hibernate/JPAエンティティのデフォルトコンストラクターn-argsコンストラクターの上書き
- WPF MVVMでカスタムタイプのデフォルト値を復元するにはどうすればよいですか?
- Javaメソッドを呼び出して、H2データベースの新しい行のデフォルト値を生成します
- オブジェクトのPostgreSQLjson配列、見つからない場合はプロパティのデフォルト値0
ご覧ください https://kotlinlang.org/docs/reference/visibility-modifiers.html
特に、クラスとインターフェースに関する2番目の段落。
これらの例から、もし可能であれば、インターフェースの代わりに基本クラスを使用することが提案されます。これは次のようになります。