アプリ版:「スタンプのみでお礼する」機能のリリースについて

オブジェクト指向で、なぜクラスを使わず、
オブジェクトをつかうのでしょうか?
よくクラスは設計図という、あやふやな説明しか、教本には書いていませんが

質問1.クラスの変数はどういう状態になっているのですか?
質問2.
なぜオブジェクトを使うの場合、変数などに、
他の変なデーターが入っているオブジェクトをつかうのですか?
オブジェクトなどをつかうとき、変数などがカラの方がスッキリしてると思うのですが?

20冊ぐらい教本を見て見たのですが、この辺のことの説明がどの本もアヤフヤでわかりません

質問者からの補足コメント

  • 質問3
    なぜクラスを使わないのかも教えてもらえればありがたいです

      補足日時:2018/02/03 19:14

A 回答 (8件)

質問1


実装で求めた値になっているでしょうね。
質問2
なんの話ですかねぇ

それぞれ、具体例を補足で示してください
    • good
    • 0

まず、言葉の意味を考えましょう。


プログラミング用語であっても、元になった単語の意味を強く意識しています。

class
https://dictionary.goo.ne.jp/word/en/class/
> 1 (人・物の)部類,類,種類

クラスとは、オブジェクトの分類や種類を表わすためのものです。
「オブジェクト(物)」そのものではない、ということです。

オブジェクト指向プログラミング言語を設計する際に、オブジェクトは分類に分けることにして、その分類で振舞いを決めるようにしよう、と考えた人がいました。
分類ではオブジェクトがどんな属性やメソッドを持っているか、等を定義します。
オブジェクトを作る際には、どの分類かを指定するようにします。

そういう考えで作られたプログラミング言語なのですから、使うのはオブジェクトです。
クラスはオブジェクトの性質を決めるために用います。
「クラスを使わない」のではなく、「使う」の意味や目的が違うのです。


で、クラスだけがオブジェクト指向を実現する方法ではありません。
今シェアの多いプログラミング言語で採用されている、というだけです。
他の手法(クラスを使わない等)でオブジェクト指向を実現してる言語もたくさんあります。

また、プログラミング言語でやっていることがオブジェクト指向の全てではありません。
各プログラミング言語は、都合のいいように、機能を取捨選択したり、拡張したりしています。
JavaとC++とでは、別物です。

その20冊って、どんな本なのでしょうか。
違う言語だったり、理論と言語解説が混ってたりすると、混乱するかもしれません。


> 変数などがカラ

まず、今のコンピュータでは、厳密な意味で「カラ」にすることはできません。
変数x を定義したら、最低限
・「変数x」が定義されている、という情報
・「変数x」にどんなものが収められているか、という情報
の2つを記憶する必要があります。

カラにするには
 「変数xはカラである」、という情報
を記憶しなければなりません。

ここで、プログラミング言語や実装方法によって、「変数x」にどんなものが収められているか、という情報をどうするか、
対応策が違ってきます。
・カラの方がすっきりする、と考えて、「変数xはカラである」という情報を**わざわざ**書き込む
・「変数xは○○である」って情報が無いと、使う意味が無い。よって、利用することすらできないように制限する。
・余計なことはしない。プログラマに任せる。

「変なデーターが入っているオブジェクト」というのがnull とか Noneとかのオブジェクトのことを言っているのなら、
それが「変数をカラ」にした結果です。

Javaで「ローカル変数〜は初期化されていない可能性があります。」等とエラーになるのは、2番目のやり方。

CやC++では「余計なことはしない。プログラマに任せる」の方針の元、何もしません。
その結果、「変数にどんなものが収められているか、という情報」を書くためのメモリ領域に何かが書いてあっても、そのまま放置します。
    • good
    • 1

そこに疑問を持ったら


クラスを使わないオブジェクト指向言語
を使ってみてもいい... かな?
    • good
    • 0

> 質問1.クラスの変数はどういう状態になっているのですか?



構造化プログラミング言語で「関数」を作っても「関数の変数はどういう状態になってるのか」ってのは「適切な引数(変数)を与えないと何もない」か、あるいは内部的に閉じ込められた変数は「そのまんまの状態」になっています。
同様に、クラスの変数・・・これややこしいな(苦笑)、も「外部から与えられる」「初期化して起動する」とかしないと「何もない」か、あるいは最初にテンプレとして設計された状態の「まま」になっています。

注: 実はクラスには「クラス変数」なるモノ(機能)を持ってるプログラミング言語もあって、「クラスの変数」って言い方は非常に紛らわしい。隠蔽するにせよ外部からのアクセスを許可するにせよ、通常、「メンバ変数」あるいは「インスタンス変数」と言う用語・・・多分(笑)、がある。そのプログラミング言語によって「名前が変わる」のがまた紛らわしい(笑)。

> 質問2.
なぜオブジェクトを使うの場合、変数などに、
他の変なデーターが入っているオブジェクトをつかうのですか?
オブジェクトなどをつかうとき、変数などがカラの方がスッキリしてると思うのですが?

まず、何度も書いてますが、ザックリ言うと「オブジェクト」と言うのは「データ型」一般を指しています。
今回のように、「クラス設計をして"実際それを使用する"状態に持ち込む」時、インスタンス化(あるいは実体化)、と言う・・・多分これも「用語」がありますね。

注: 「多分」と言うのは、これもビミョーに言語によって違う場合があり・・・要するに「用語」としてはコンセンサスが得られてるかどうか全く自信無し、です。実際、C++辺りでは「インスタンス」じゃなくってそのまま「オブジェクト」と呼んだりするケースがあるみたいで、ホントこの辺、ぶっちゃけ「用語」がメチャクチャです(苦笑)。

つまり、上記の質問は

> 質問2.
> なぜインスタンスを使う場合、インスタンス変数などに、
> 他の変なデーターが入っているインスタンスをつかうのですか?
> インスタンスなどをつかうとき、インスタンス変数などがカラの方がスッキリしてると思うのですが?

だと思いますが・・・・・・。
これはぶっちゃけ「初期化」の問題であって、

「他の変なデーターが入っているインスタンスをつかうのですか?」

ってのは「そういう初期化が必要なクラスを設計したからだ」としか言いようがありませんね(笑)。
もう一度言いますが、「クラス」が「ユーザー定義データ型作成機能」だとすれば、「他の変なデータ」が何を指してるかは知りませんが、インスタンス化の際にそれが必要だとすれば、「それが必要なデータ型として設計したからだ」と言う事です。
そういうのが必要としないなら「必要でない」クラスとして雛形を作成すれば良いのです。

# Python での例

class Hoge(): # Hoge型 と言うデータ型を作成

def __init__(self, a, b): # 初期化でa, bと言う2つの変数が初期化として必要
    self.a = a
    self.b = b

# Python での実行

>>> var = Hoge(1, 2) # インスタンス変数a, bに値を与えてインスタンス化(実体化)させる。
>>> var.a
1
>>> var.b
2
>>>

上記のように「ユーザ定義データ型としてインスタンス変数が2つ必要だと設計した」からインスタンス化の際、初期化として2つの値が必要なのです。

> インスタンスなどをつかうとき、インスタンス変数などがカラの方がスッキリしてると思うのですが?

もちろんそういう事も出来ます。

# Python での例

class Fuga(): # Fuga型と言うデータ型(オブジェクト)を作成

  def __init__(self):
    self.val = None # カラとして None を指定

# Python での実行例

>>> var = Fuga() # 今度は初期化で引数は与える必要がない
>>> var.val   # インスタンス変数は?
>>>         # 何も返ってこない(カラだから)


上記はPythonでの例なんで、クラスを実体化(インスタンス作成)する際にJava等に於けるnewメソッドは用いませんが、基本的には同様な事は可能でしょう。
もっとも、例えばC++みたいな比較的低レベルな言語だと「カラ」を表現するのもちと難しいかも、ですね。Python辺りの「高級言語」だとNoneとかありますが、多分C++だとちょっと難しいかもしれません。

> 質問3
> なぜクラスを使わないのかも教えてもらえればありがたいです

何度も繰り返しますが、「クラス」は「ユーザー定義データ型」です。従って「データ型」として使いたい「雛形」を作るわけで、直接使わないのは当たり前ですね。
「クラスを使う」のではなくって、「クラスを実体化(インスタンス化)」した状態の「オブジェクト」(インスタンス)をオブジェクト指向プログラミングでは用いるのです。
    • good
    • 1

うん、そうね、ちょっと用語の混乱があるかもしれないですね。



ザックリ言うと、オブジェクトとはプログラミング用語でほぼ「データ型」と同じ事を指します。まあ、同じ、って考えて良いでしょう。「データ型」のカッコつけた言い方が「オブジェクト」だ、って捉えて当分は大丈夫です。

ところで、現代のプログラミング言語の「形式」ってのはまぁ色々とありますが、メジャーなモノは次の2つの形式です。

・構造化プログラミング言語・・・C言語、Pascal等
・オブジェクト指向言語・・・C++、Java等

構造化プログラミング言語とは、基本的にデータに対しての操作を「関数」として定義していってプログラミングしていく言語ですね。関数を中心としてプログラムを組み上げる。これは言い換えると、プログラムの中心が関数である以上、データは「補助的な役割/立場にある」って事を暗示しています。
一方、オブジェクト指向言語とは、さっき言ったように「オブジェクト」がほぼ「データ型」を意味するとすれば、「データを中心にプログラムを組んでいくように意図/設計された言語」になりますね。さっきと逆に、プログラムの中心は「データ」(オブジェクト)で関数が「補助的な立場にある」って事です。
実は、このように定義を見ると、どっちの言語でも「スタイルの問題として」オブジェクト指向なプログラミングも組めますし、逆にオブジェクト指向言語で「構造化プログラミング」な形式でプログラムする事も「可能」だと気づくんじゃないでしょうか。そうですね、所詮は「スタイルの問題」ですから(Javaみたいに頑固な言語もありますが)。
ただし、プログラマがどっちのスタイルを選ぶ、ってのは「自由」ですが、プログラミング言語、つまりツールの性質として「片方は一方のスタイルが得意なように敢えて設計されている」と言う事実が立ちはだかります。C言語で「オブジェクト指向的なプログラミング」は可能ですが、特化されてるC++に比べると「同じ事をやるのに遥かに面倒くさい手順を踏まなきゃならない」事が多い、ってのが事実です。「特化した」道具とはそういうものですよね。

さて。
上記のような定義で見ると、「オブジェクト指向」と言うプログラミング方法は、「データを中心にプログラムを組み上げていく」手法だ、と言う事を見ました。
んで、この定義で見ると、実は「オブジェクト指向プログラミング」と言うのと「クラス」ってのは本質的には全く関係がない・・・少なくともクラスは「必須の要素ではない」って事が分かると思います。実際、全ての「オブジェクト指向」を名乗るプログラミング言語の10%くらい(多分?)はクラス自体が無かったりします。
まあ、そういう例外もあるんですが・・・正確に言うと、実はオブジェクト指向プログラミング言語ってのが「具体的に何を指すのか」・・・言い方変えると「どういう実装の言語がオブジェクト指向を名乗れるのか」ハッキリした定義が無いのが実情なんで(さっきも書いた通り、プログラマがやりたい「プログラミングスタイル」を補助する為にバラバラに作られてるんで当然と言えば当然ですが)・・・90%くらいの「オブジェクト指向言語」が取り扱ってる「クラス」が一体何なのか、と言う話をします。
とは言ってもいわゆる「クラス」が何なのか、と言うのは簡単で、さっき書いた通り、「オブジェクト」は「データ型」を(ほぼ)意味し、「オブジェクト指向」が「データを中心としてプログラムを組み上げる事」を意味するとすれば、「クラス」ってのは要するに「ユーザー定義データ型作成機能」の事に他なりません。
構造化プログラミング言語の場合、いわば関数とは「ユーザー定義関数」と言って良く、そのプログラミング言語が提供している関数「以外」でもプログラマが自分の好きな関数を好きなように定義して使う事が出来ます。
オブジェクト指向言語の場合、対立する概念、「データ型」(オブジェクト)を自分で好きに定義して使用する事が出来る・・・要するに関数に代わって「クラス」と言う機能がある、って考えてまあ間違ってないでしょう。

※正確に言うと、構造化プログラミング言語でも「ユーザー定義データ型」を作る機能は搭載されてて、それらは「構造体」とか「レコード型」と呼ばれる事が多い・・・けど本筋に関係ないので端折ります。

もう一度書くと、「クラス」と言うのは「ユーザー定義データ型作成機能」の事です。つまり「こんなデータ型がほしいな」と思った時、その「雛形」・・・最近ではテンプレート(テンプレ)とか言いますが(注: 英単語は同じですが、C++のテンプレートの事ではありません。要するに「使い回しが効く」それこそ「設計図」です)、を「クラスとして」記述するのです。構造化プログラミング言語で「こんな関数が欲しいな」って思った時にその関数を書く、ってのと丸っきり同じです。
従って、構造化プログラミング言語で、関数を書いても「具体的に引数を与えないと動かない」のと同じで、クラスはあくまで「雛形」なんで、適切なブツを与えないと「動かない」わけですよね。同じです。
    • good
    • 1

>>オブジェクト指向で、なぜクラスを使わず、


オブジェクトをつかうのでしょうか?

オブジェクト指向の言葉でいうと、「オブジェクトをつかう」は「インスタンス」をつかうという言い方になるでしょう。
なお、オブジェクト指向でも、インスタンスを作らず、クラスを使うことは割とあります。ただし、安物の入門書ではそこまで記載されてないかもしれません。

>>よくクラスは設計図という、あやふやな説明しか、教本には書いていませんが

入門書ですし、厳密に説明したら初心者にとっては難しくなるからかも?

まずは、ちゃんとしたオブジェクト指向の書物を購入されたほうがいいと思います。
そして、実際にプログラミングをしてみることをお勧めします。
    • good
    • 0

「なぜクラスをつかわないかも」とあるが。



コードを書いてる実装者には、見えない形であっても、
クラス定義が必要な言語でいうところのクラス定義に相当するものがどこかにあって、それを使ってのインスタンス生成である。
ただ、それを意識しなくても、気楽に使える言語や環境かもしれないし。

クラス定義を意識的にやるような言語であっても、
自分がクラス定義してない既にあるクラス定義より、
インスタンス生成してるだけだと。

その状況は、様々だけど。
実装者がどう思ってるかにかかわらず、
オブジェクト指向なら
何らかの形のクラス定義なり型情報より
インスタンス生成してるとおもうので。

「なぜクラスを使わないか」
とかの質問以前。

用語や、言葉の違いはさておき、
クラスに相当する型情報からのインスタンス生成
しているような状況になってるはずだとおもいます。

オブジェクトとという言葉をどんなレベルでつかってるかなど。
用語の違いなどあって。
伝わるか怪しいですが。

表面上の用語とかより、
実行時に、メモリやプロセッサーでなにがおこってるかに注目して思考したら、
惑わされることはないと思います。

以上です。
    • good
    • 0

言語が固定されてないから回答しずらいですが。



クラス定義はコンパイルした時に、静的に決まるものだと思います。
クラス定義は型の定義だと思うので。
言語や環境によって諸事情違うかもしれませんが。
実行時にはじめて、その型自体が利用されるときに、
メモリ上に型情報が読み込まれるです。

「クラスの変数」という言葉を使われてましたが。

クラス定義時に、staticとしたメンバー変数は、
動いてるプロセス中に一個しかありません。

一方、staticにしなかったメンバー変数は、
クラス定義よりnew演算子より生成したインスタンスごとに、別メモリが
割り当てられてます。

同じメンバーでも、
メソッドのほうは、
static有無にかかわらず、
プロセス中に一個だけ
作られます。
実行時に、
そのメソッドの定義にしたがったコールスタックが
スレッドごとに別々に
作られるので。
内部で定義されてる
ローカル変数は、本来的にスレッドセーフです。
そのローカル変数より
参照されてる情報が、
スレッドアンセーフとなることは、十分あるので。
やってるソフトウェアの仕様や実装内容によっては、
排他制御も必要に応じてする。

メソッドがstaticなのか、
そうでないかは。
thisのコンテキストで実行されるかどうかの違いです。
そのインスタンスに対して、
そのインスタンス固有のメソッド変数などにアクセスするようなコンテキストで
実行することを目的にするなら、staticにしないし。
インスタンスごとによらず、
そのクラス定義としての
全般役割にしたければ、
staticにしないだけ。

他にも、C++だと
クラスに属さない。
単なる関数も定義できる
その関数にstaticをつけるかどうかは、
これまでのstaticとは、ぜんぜん、意味が違います。
staticがあると、同じ
コンパイル単位(ソースコード)内からしか、使えないとかそういう使い方だったと
思いますが。
そこらへんの制限を特に指定しない、クラス定義に書いてない関数は、
どこからでも(どこぞのクラス定義の実装中からでも)
使えたりする


オブジェクトという用語を
インスタンスのことなのか。
クラス定義とインスタンスの両方含めたものについてで、
使ってるのか不明ですが。

簡易的なスクリプト言語では、動作中に、
各々、インスタンスごとに、
型の定義内容を変動させたりできるものもあるです。

あんまりクラス定義とか、考えずに気楽に使ったりする言語もあるかと。

「変数などに、他の変なデータが入ってるオブジェクト」
という言い回しあるですが。

なにもしないときに、
なにが入ってるのか。
0が入るか、不定値が入るか。
などは、言語や、
使う変数をどのメモリ領域に対して、どのように作ったかなどにより、様々です。

初期化処理のようなものを実装したりするでしょうが。

それをコンストラクタでやったり。
Factoryメソッドのような方式でやるとか。
初期化処理も、考えて実装するものだと考えます。

これで、回答になってるのか不明ですが。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!