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

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

ただいまの
回答率

87.36%

関数とクラスの違いがいまいちわかりません。

解決済

回答 5

投稿

  • 評価
  • クリップ 3
  • VIEW 10K+
退会済みユーザー

退会済みユーザー

phpとjavascriptを使っているのですが、関数とクラスの違いがいまいちわかりません。
クラスは設計図のようですが関数も何度も使う物なので同じように感じてしまいます。

初心者にもわかるように教えていただければ幸いです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+5

関数は状態を持ちません。状態とは関数を呼び出す前と関数を呼び出した後の、何かしらの値の事です。関数の中でグローバル変数を変更すれば、それは状態が変わったと言えるかもしれませんが、その関数にとって値が更新出来る物が1つに定まってしまいますよね。

そこで以下を見て下さい。

<?php

class Counter
{
    protected $n;

    public function __construct(int $n)
    {
        $this->n = $n;
    }

    public function result()
    {
       return $this->n;
    }

    public function add()
    {
       $this->n++;
    }
}

これは add と result というメソッドを持ったカウンタクラスで、初期値を与えられる様になっています。ですので以下の様に 3 からスタートするカウンタ c1 と 5 からスタートするカウンタ c2 をそれぞれ異なる値を保持したまま作る事が出来ます。

$c1 = new Counter(3);
$c2 = new Counter(5);

$c1->add(); $c1->add(); $c1->add();
echo $c1->result(); # 6 が出る

echo "\n";

$c2->add(); $c2->add(); $c2->add();
echo $c2->result(); # 8 が出る

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/30 20:38

    >>>
    関数の中で値を変えたとしても、関数を抜けると元の値に戻ってしまいますよね。
    参照渡しを使って、関数が関数の外側の値を変更する事は出来ます。しかし変更したい物が増えてきたら、参照渡しの引数をどんどん増やさないといけなくなりますよね?もし同じ様な関数がいっぱいあれば、全ての関数を直さないといけなくなります。大変ですね。


    恐らく関数に複数の値を引数として指定すると、どんどん引数を増やしていかないといけないので、悪いソースになってしまう。

    よってこのように引数が複数になる場合、関数とよく似ているが引数を増やさずに済むクラスを使うという事でよいでしょうか?

    おかげさまで何となくわかってきました。

    キャンセル

  • 2018/01/30 23:27

    はい。その認識で良いと思います。クラスにはその他メリットがあって、クラスの中に保持する値を隠蔽してくれる働きがあります。以下はなんとなく理解して頂ければよいかと。

    例えば人間という情報があります。人間という情報には名前、年齢、趣味があります。この情報を200人分管理しないといけません。

    こういった場合、名前を200個、年齢を200個、趣味を200個、と変数を作るのではなく、人間という情報に名前、年齢、趣味、という属性を持たせ、それを200個持った方が管理しやすいですよね。これを簡単に行えるのがクラスです。

    キャンセル

  • 2018/01/31 11:10

    ありがとうございます。

    >>>
    こういった場合、名前を200個、年齢を200個、趣味を200個、と変数を作るのではなく、人間という情報に名前、年齢、趣味、という属性を持たせ、それを200個持った方が管理しやすいですよね。これを簡単に行えるのがクラスです。
    >>>

    むずかしいですね。なんかJSのオブジェクトにも似ているなと思いました。
    隠ぺいとはカプセル化の事でしょうか?変数を外から変更できないようにできるという事ですかね?

    とりあず初心者の私は、引数をいっぱい使いたい時に関数を使っても実現はできるが引数がいっぱいになるのは管理がしにくいので、そのような場合に関数ではなくクラスを使うと理解しておきます。

    ありがとうございました。

    キャンセル

+3

クラスは「構成要素 または 役割」、関数は「機能」と思うといいかもしれません。

例えば「ボールペン」というクラスがあったとします。
ボールペンの構成要素を大きく分けると、
「インクの色・ボディの色・インクの量」などの「データ」と
「ペンの後ろをノックするとペン先が出る」などの「機能」になります。

プログラムではこの「データ」を「プロパティ(変数)」として定義し、
「機能」を「関数(メソッド)」として定義します。

このクラスを使えば「赤色のインクが出るボールペン」「ボディが白いボールペン」など、「基本的には同じだけど、一部が違うもの」を簡単に表現ことが出来ます。これが「設計図」とも言われる所以です。


もう1つ例として、「ボールペンを管理するクラス」を考えます。
このクラスは「インクの無くなったボールペンを破棄する」「補充用ボールペンを購入する」などの機能(関数)を持っています。

一見するとクラスではなく関数だけあればいいようにも見えます。事実、PHPやJavascriptではクラスでなくても動作します。
ですが他の言語だと「全てのスクリプトは何らかのクラスでなければならない」という仕様になっているものがあります。
この場合、「ボールペンを管理するクラス」は「構成要素」と言うよりは「役割」と言った方が分かりやすいと思います。

なお、「役割」の場合でも「データ(プロパティ/変数)と機能(関数/メソッド)を持つ」という原則は変わりません。
「ボールペンを管理するクラス」のデータの例で言えば「補充する時は何本ずつ購入するか」などが考えられます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/31 13:39

    とてもわかりやすかったのでだいぶわかりましたありがとうございます。

    クラスは関数と似ているが、関数よりもっと便利に再利用ができる機能なのですね。
    関数だと引数だらけになって使いにくいと思った時に、クラスを使うのですね。

    また、ゲームをJSで作った際にデータを保存して、置きたいことがあります。例えば現在どのステージをplayしているかや今までの総合得点などです。

    このような場合、グローバル変数を使わないと情報が初期化されてしまいますが、クラス内の変数であれば保持できるのでしょうか?
    これも関数内の変数にはないクラスのメリットですか?

    キャンセル

  • 2018/01/31 15:21 編集

    「クラスにすれば保持される」ということはありません。クラスをグローバル変数に入れれば保持されるとは思いますが、私はJSは詳しくないのではっきりとは言えません。
    今回の質問とは本質的に異なる質問なので、自分で試してみるか別質問として投稿した方が確実だと思います。

    キャンセル

  • 2018/01/31 15:52

    了解しました。ありがとうございました。

    キャンセル

checkベストアンサー

+2

関数はデータ(引数)を入力したらなにかしら結果を返す一連の処理をまとめたヤツです。
基本的に同じデータを入れたら同じ結果を返す処理が好ましいです。基本的にです。
(乱数を返すとか時間を返すとかクロージャ使うとか意地悪は今回ナシで)

クラスはデータ(メンバ変数)の保持と、そのデータに対して作用するメソッド(メンバ関数)を一塊としてまとめたヤツです。
いろんな機能を詰め込めますが、使う時に実体化(new)させたりちょっと手間がかかります。
同じデータを入れても、メソッドを呼び出す順序や回数で結果が変わってくるような処理が大得意です。
データ(状態)をカプセル化し、他のプログラムからデータが変更されるのを防ぐといった使い方も得意です。(設計しだいですが^^)
ただ複雑に多機能化しすぎるとテスト・デバッグが難しい厄介なクラスが出来上がったりします。
なんでも詰め込めまずに、役割分担の設計バランスが重要になってきます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/02 18:44 編集

    ローカル変数は変数スコープ(関数の場合は関数)を抜けると終わりです。
    そしてインスタンスもローカル変数に代入するので、基本的には変数スコープを抜けると終わりなのですが、厳密な話をしだすとアクセス手段がないというだけで消えてはいません。

    ちょっと難しい話になってくるのですが、
    インスタンスがメモリから消えるタイミングは、昨今の言語ではガベージコレクション(GC)という
    ゴミ収集車みたいなやつが削除してよいと判断し、削除を実行した時という言い回しになってしまいます。

    そして、webサーバーのモジュールとして動かすphpの場合は、
    1リクエスト毎に1プロセスが作られ、リクエストが終了すればプロセスが終了するので、
    GCで消えるというよりもプロセスの終了によりインスタンスが消える、というようなイメージをしていたほうがいいかもしれません。

    ただし、phpでもApacheやnginxの力を借りず、
    1プロセスを使いまわすような設計で組み込みWEBサーバーを実装すれば、
    リロードで消えない挙動も実現できることでしょう。
    phpで組み込みWEBサーバーはちょっと自分もやったことはないので難易度が高そうですが、
    phpでソケットサーバー程度ならちょくちょくある話で、その時は関数のみでやるよりも、
    オブジェクト指向とクラスの力を頼ったほうが、開発効率は良いと思います。

    ブラウザで動かすJavascriptもリロードで生成したインスタンスは消えます。
    リロードという行為により、いったんプロセスが終わるため、メモリからプログラムが解放されインスタンスは消えるということです。

    Javascriptのclass構文は確かにprototypeの糖衣構文ですが、
    自分的には継承周りでだいぶ楽になりましたよー。
    物足りないと感じたならばTypescriptやScala.jsといったAltJSとかでしょうかねぇ^^

    キャンセル

  • 2018/02/04 13:05

    ありがとうございます。別質問にした方がよろしければ別質問にします。

    >>>
    変数のスコープとは、その変数が参照できる範囲のことです。

    とあったので変数スコープとは関数スコープ内の変数なら、関数スコープ内がその変数の変数スコープになるという事ですかね。
    つまり、その変数はその関数内でないと一切利用できないという事ですね。


    >>>
    そしてインスタンスもローカル変数に代入するので、基本的には変数スコープを抜けると終わり

    関数のローカル変数は発揮性が高く、
    関数コールと共にメモリ内に生成され、終了するとメモリから消えます。
    このことを「状態を持たない」という言い回しで表現される事が多いです。

    つまり関数のローカル変数は、その関数の処理が終わったらないしは関数のスコープ外では消えてしまうという事で良いでしょうか?
    クラス内の変数もクラス内の処理が終わると消えてしまうという事は、関数内の変数と同じように見えるのですが、
    クラス内の変数との違いがいまいちわかりません。
    基本はこの通り同じだが、厳密な話をしだすとアクセス手段がないというだけで消えてはいないという事が唯一の違いという事でしょうか?

    つまりクラス内の変数が本当に消えるのは、クラス内を出た時ではなく、
    GCで消えるというよりもプロセスの終了によりインスタンスが消える、というようなイメージという事でしょうか?

    キャンセル

  • 2018/02/05 16:49 編集

    >その変数はその関数内でないと一切利用できないという事ですね。
    そのとおりです。

     >つまり関数のローカル変数は、その関数の処理が終わったらないしは関数のスコープ外では消えてしまうという事で良いでしょうか?
    はい。スコープをぬければ消えてしまいます。

     >クラス内の変数との違いがいまいちわかりません。
    これはクラスを実体化(インスタンス化)する、という行為にピンとこられていないのかなと思いました。

    「変数」と「その中に入る値」は別物というご理解はありますでしょうか。
    変数は名前がつけられる器であり、インスタンスとは器に入れるモノです。
    そして器が消えるタイミングとモノが消えるタイミングは別です。
    器が消えても、モノが残っていれば利用できます。
    そして、クラスの変数(インスタンス変数)とは「モノの中に入っている、器」のことです。
    実体化されたインスタンスのインスタンススコープの中で生きてます。
    (状態が持てると表現)

     >インスタンスもローカル変数に代入するので、基本的には変数スコープを抜けると終わり

    私が混乱する言い方をしてしまいましたね。
    インスタンスの消えるタイミングはちょっと脱線気味かな~と思ったので、変なニュアンスとなってしまいました。


    一つのコードブロックだけでみると書き方の違いしか見えてこないかもしれませんが、
    複数行に渡って処理を分割できるクラスは、別のスコープにインスタンスを渡すだけで、気軽にそのクラスの機能(インスタンス変数だったりメソッド)が利用できるということでもあります。この性質をうまく使えるようになると、関数とクラスの使い分けが出来るようになったと言えるでしょう。

     >GCで消えるというよりもプロセスの終了によりインスタンスが消える、というようなイメージという事でしょうか?
    条件付きです。PHPとJavascriptならば、そのイメージで初心者の方はOKです。GCはいっかい忘れて下さい。なぜならPHPは1リクエストでプロセス終了、Javascriptもページ遷移またはリロードすれば、
    雑なメモリ管理でも問題となることが少ないため、危険な言い方ではありますがなんとかなります。
    (いろんな人に怒られそう><)

    ただ中級者以上ではそうはいきませんので、
    クラスの挙動は私の説明のような乱雑なざっくりイメージだけでは危険です。
    時が来ましたら、改めて正しいクラスの挙動を勉強してください。
    慣れるまでは当初の趣旨通り、引数の数で使い分けて良いと思います。
    道具って仕組みはわからなくても、数をこなせば使いこなせますよね。
    例えば1+1=2という証明方法・理屈を知らなくても、足し算という道具は使いこなせます。
    使いこなすための最初の突破口として「引数の数」はありでしょう。

    キャンセル

0

データとそのデータに対する操作を行う関数をまとめて持つ型がクラスです

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

関数はいわゆるサブルーチンです。大雑把に言えば下請け処理です。

クラスは複数の関数と変数を包括して定義できる概念です。一方、この概念を実体化したのものはオブジェクト(インスタンス)といいます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/31 12:33

    関数をさらにまとめた関数などのグループ、処理の塊という事でしょうか?

    キャンセル

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

  • ただいまの回答率 87.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る