質問: インスタンスメソッド内から、staticプロパティとstaticメソッドは呼出可だけれども、 staticメソッド内から、普通のプロパティと普通のメソッドが呼び出し不可なのはナゼですか? 仕様だから??
回答: 仕様だから・・・なんですが、こういう質問が出るということはオブジェクト指向の考え方が身についていない証拠なわけです。ウチの新人君にこの辺を解説するときの定番を書いてみます。オイラが [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") 屋なので用語が [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") になってしまうあたりはご勘弁を。 「人」クラスを設計するとします。クラスのメンバとは(静的、非静的とも)「そのクラスに属する何か」です。無関係なものをクラスの中に持ってこないことが重要です。 非静的メンバというのは「個々のインスタンスで違うもの」です。例えば「姓」「名」は人なら誰もが持っていて、みな違う(同じ場合もある)わけです。 [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") っぽい疑似言語でこの辺を実装してみたら、こんな感じになるのかな? ``` class human_type { string_type FirstName; string_type FamilyName; } ``` では「年齢」はどうでしょうか?人ならだれでも持っていて、みな違う、わけですが、これをメンバ変数( [php](/questions/tagged/php "'php' のタグが付いた質問を表示") でいうところのプロパティ)に持ってしまうと「人」インスタンスのすべてに対して毎日再計算する必要があります。これでは不便なので、メンバ変数に持つのは可能な限り不変なものであるほうが有利です。なのでメンバ変数として持つべきは生年月日で、年齢は「メンバ関数」にします。 ``` date_type BirthDay; integer_type calculate_age(date_type d = today()); ``` 静的メンバ変数とか静的メンバ関数(メソッド)というのはまったく違い、すべてのインスタンスで共通なもの(であるがゆえに1つだけあればよい代物)です。「人」クラスでいえば「今の総人口」「性別が何種類あるか」などはインスタンスを特定する必要がない共通な性質です。(人クラスの各インスタンスが全員「総人口」を把握していなければならないか、というのはクラスの設計方針次第だったりしますが、ここではおいときます) 非静的メンバ変数、非静的メンバ関数は「誰か」つまりはインスタンスを特定する引数があって初めて意味があります。 [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") ならば `this` ですし [python](/questions/tagged/python "'python' のタグが付いた質問を表示") なら `self` です。 A さんの誕生日とか B さんの年齢を求める、ならば意味があり、「皆に共通な姓」「皆に共通な年齢を求める」というのに意味がない、ということは理解できるはずです。 逆に静的メンバ変数、静的メンバ関数は、すべてのインスタンスについて共通なものですから `this` は不要というかあってはならないわけです。 A さんに聞いた総人口と B さんに聞いた総人口が異なっていたら「共通」ではないわけです。 というわけで長々と書きましたが * 非静的メンバ関数から静的メンバにアクセスできる理由 `this` が存在する非静的メンバ関数から `this` の不要なメンバをアクセスする=可能 * 静的メンバ関数から非静的メンバにアクセスできない理由 `this` がない静的メンバ関数から `this` が必要なメンバをアクセスする=無理 このように「静的メンバ」と「非静的メンバ」とは目的も用途も異なる代物なのであることを理解しておいてください。 ちなみにこの後には新人君に対する演習が続き、この「人」クラスにおいて - 非静的メンバ変数に持つべき何かを1つ以上挙げなさい - 非静的メンバ関数にすべき何かを1つ以上挙げなさい - 静的メンバ変数に持つべき何かを1つ以上挙げなさい - 静的メンバ関数にすべき何かを1つ以上挙げなさい となるわけですが、読者の方々も試してみてください。