質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

2回答

1755閲覧

プロパティ(フィールド)の値を変更されたくない場合について

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

1グッド

0クリップ

投稿2020/08/30 23:53

編集2020/08/31 09:18

初歩的な質問かもしれませんが、以下のような状況に困っています。
現在kotlinにて実装しているのでサンプルはkotlinになりますが、回答はJavaでも問題ありません。
オブジェクト指向として?正しい実装はどれか教えてください。

現在の実装

Userクラスがあります。

kotlin

1class User { 2 val condition: Condition = Condition() 3 4 fun grow() { 5 condition.age++ 6 condition.height++ 7 condition.weight++ 8 } 9}

UserのプロパティであるConditionクラスは以下です。

kotlin

1class Condition { 2 var age: Int = 0 3 var height: Int = 0 4 var weight: Int = 0 5}

Conditionクラスでは年齢、身長、体重をプロパティとしていて、Userクラスのgrow()メソッドにて年齢、身長、体重が1ずつ上がっていきます。(普通に考えると変ですが。。。)

困っていること

このときにMainクラスでUserクラスをインスタンス化して運用したいのですが、MainクラスからConditionの値が直接変更されてしまいます。

kotlin

1class Main { 2 val user: User = User() 3 4 fun main() { 5 // getはされてもよいと考えている 6 val age = user.condition.age 7 8 // setはさせたくない 9 user.condition.age = 100 10 } 11}

user.conditionを変更することはできません。(valとしているので)
しかし、user.condition.ageを変更することができてしまいますので、これを制止したいです。

いわゆるConditionクラスの値を、Userクラス内では自由に変更できるが、その外からは読み取り専用というようにしたいと考えています。

考えたこと

Conditionクラスをやめる

Userのプロパティに年齢などを持たせて、val とすることで、当たり前ですが上記の実現したいことができると考えています。そもそもクラス設計がおかしい、というのであればこの案に最終的にはたどり着くかと考えています。

Conditionクラスをコピーして渡す

UserクラスのConditionのgetterメソッドを加工して、別の実態を渡す。そうすればそのConditionクラスの値を書き換えられない気がする。(なんとなくです)


ほかにもval をvarに変えるなど考えましたがなかなか納得のいく実装になりませんでした。

考え方、正しい実装を教えていただきたく思います。
よろしくお願いいたします。

ozwk👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/08/31 00:07

Condition を変更し、メンバ変数を非公開にしてゲッターのみ公開する(つまり Condition をイミュータブルにする)方法を使うことは可能ですか?
miyabi_takatsuk

2020/08/31 00:35

> 回答はどの言語でも大丈夫です。 言語によって、仕様も実装方法も考え方も変わってしまうので、 今回はKotlinのようですし、Kotlin限定での話にした方がいいかと。 (ただし、他の言語でもなんらかの方法がある、という考え方はある意味では間違っていない)
退会済みユーザー

退会済みユーザー

2020/08/31 09:16

Zuishinさん 返信が遅くなってしまい申し訳ございません。 既に回答されているozwkさんの実装であればどうか。ということでしょうか。
退会済みユーザー

退会済みユーザー

2020/08/31 09:17

miyabi_takatsukさん 確かにおっしゃる通りでした。 実際にはタグ付けしたJava, kotlinでの希望でした。すみません。
Zuishin

2020/08/31 09:54

そうです。Condition がイミュータブルで問題ないのならそれがスマートかつ手軽だと思います。そうできない制限があるのなら他の方法をとらなくてはいけませんが。
guest

回答2

0

ベストアンサー

Conditionをイミュータブルにする方法

kotlin

1class User { 2 var condition: Condition = Condition() 3 get 4 private set 5 6 fun grow() { 7 condition = Condition(condition.age+1,condition.height+1,condition.weight+1) 8 } 9} 10 11 12class Condition(val age: Int = 0, val height: Int = 0, val weight: Int = 0) 13 14 15val user: User = User() 16 17fun main() { 18 // getはされてもよいと考えている 19 val age = user.condition.age 20 21 // setはさせたくない 22 //user.condition.age = 100 23 24 println(age) // 0 25 user.grow() 26 println(user.condition.age) // 1 27} 28

投稿2020/08/31 02:08

ozwk

総合スコア13551

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/01 00:49

回答ありがとうございます。 確かにこの実装であればやりたいことが実現できていると考えています。 しかし、今回のようにgrow()メソッドでは、年齢・身長・体重を全て変更していますが、別メソッドにて体重のみ変更があった場合には、体重のみ値を変更してConditionインスタンスを生成することになります。 私自身、知識がないため質問しているので確実に違っているとは言えないのですが、なにか違和感があるような気がします。
guest

0

一番簡単に考えたら(conditionはUserを介してしか書き換えないのなら)、
Userのconditionをprivateに指定して、
UserにgetAge()関数などを追加してそこでreturn condition.age
するとかでしょうか

投稿2020/08/31 01:55

q_sane_q

総合スコア610

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/01 01:06

回答ありがとうございます。 個人的には私もこの考え方です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問