メンバにアクセスできる件について
PHPでスーパークラスで定義したprivateのメンバにサブクラスからアクセスできる件について
質問です。
class TestClass {
private $value01 = "スーパークラスの private メンバ";
public function testMethod01 () {
print "スーパークラスのパブリックメソッド";
print "<h1>{$this->value01}</h1>";
}
protected function testMethod02(){
print "スーパークラスの protected メソッド";
}
private function testMethod03(){
print "スーパークラスの private メソッド";
}
public function getMethodList(){
print_r(get_class_methods($this));
}
}
class ExClass extends TestClass{
private $value01 = "サブクラスの private メンバ";
}
$obj = new ExClass();
$obj-> testMethod01();
と上記のようにサブクラスのインスタンスから継承したpublicなメソッド testMethod01()を実行すると
スーパークラスのprivateなプロパティにアクセスできてしまいます。
これってどういうことでしょうか?privateメンバってそのクラスの中からだけしかアクセスできませんよね?
上記では、サブクラスからアクセスしているような状態にみえますがどういうことでしょうか?
ご教授御願い致します。
No.2ベストアンサー
- 回答日時:
#1です
>$obj = new ExClass();
>$obj-> testMethod01();
>ここから見える(アクセスできる)かどうかです。
というのは、スーパ-クラスを継承したExClassというサブクラスから継承元までさかのぼってという意味でしょうか?
そこはひとまず置いて考えてみると分かりやすくなると思います。
サブクラスからアクセスできるのはtestMethod1とtestMethod2です。
ここまではたぶん理解されていると思います。
ではtestMethod1(もしくはtestMethod2)から見える範囲は?
→TestClass内の各メソッドやプロパティです。
単純にこれだけの話です。なので・・・
以下メソッドは、スーパークラスで定義してサブクラスに継承されたクラスですよね。
public function testMethod01 () {
print "スーパークラスのパブリックメソッド";
print "<h1>{$this->value01}</h1>";
}
>$obj-> testMethod01();
上の継承したメソッドtestMethod01()を実行している時点でExClassのインスタンスだけど
実際はスーパ-クラス内に入りこんでTestClass(スーパクラス)として振る舞っているということでしょうか?
「入り込んで」の解釈の仕方が適切なのかはわかりませんが、そういう理解の仕方でもよいと思います。
(ちょっと適当)
また、このtestMethod01というメソッドと全く同じ内容でサブクラスでオーバーライドした場合は上記とは異なる動きになりますよね?
オーバ-ロードした場合、サブクラス内で【$this->value01】というプロパティを探す動きにかわるとおもいますが、
オーバ-ロードした場合は完全に、サブクラスとして振る舞うというような解釈でしょうか?
これはサブクラス内にtestMethod01を定義(オーバーライド)しているという意味ですかね?
こんな意味で間違ってなければ・・・
class ExClass extends TestClass{
private $value01 = "サブクラスの private メンバ";
public function testMethod01 () {
print "ここに表示されるのは?";
print "<h1>{$this->value01}</h1>";
}
}
ここでの$this->vakue01はサブクラスの値です。
なぜなら$thisはサブクラスなので。
ってここまで書いて気づきましたがオーバーロードですか?オーバーライドですか?
PHPでオーバーロードって最近はあまり聞きませんが、意味合いが異なってきますのでちょっと悩ましいです。
これはJavaチックな考え方ですかね?あんま詳しくないのでよくわかりませんが・・・
http://php.net/manual/ja/language.oop5.overloadi …
ありがとうございます。
なんとかつかめた気がします。
オーバーロードに関しては入力間違いです。ごめんなさい。
class SuperClass{
public $publicValue = "スーパークラスのパブリックプロパティ";
protected $protectedValue = "スーパークラスのプロテクティッドプロパティ";
private $privateValue = "スーパークラスのプライベートプロパティ";
public function superPublicMethod(){
print "どこからでも見えるメソッド";
}
protected function superProtectedMethod(){
print "親及び子クラスのクラス定義の中のみ参照可";
}
private function superPrivateMethod(){
}
public function superGetMethodList(){
var_dump(get_class_methods($this));
var_dump(get_class_vars(get_class($this)));
}
}
class SubClass extends SuperClass{
public $publicValue = "サブクラスのパブリックプロパティ";
protected $protectedValue = "サブクラスのプロテクティッドプロパティ";
private $privateValue = "サブクラスのプライベートプロパティ";
public function subGetMethodList(){
var_dump(get_class_methods($this));
var_dump(get_class_vars(get_class($this)));
}
}
$obj = new SubClass();
//クラス定義の外側なので private protected メソッドは不可視である。
var_dump(get_class_methods($obj));
var_dump(get_class_vars(get_class($obj)));
$obj -> subGetMethodList();
$obj -> superGetMethodList();
------------------------------------------------------------------------------------------------
array
0 => string 'subGetMethodList' (length=16)
1 => string 'superPublicMethod' (length=17)
2 => string 'superGetMethodList' (length=18)
array
'publicValue' => string 'サブクラスのパブリックプロパティ' (length=48)
------------------------------------------------------------------------------------------------
array
0 => string 'subGetMethodList' (length=16)
1 => string 'superPublicMethod' (length=17)
2 => string 'superProtectedMethod' (length=20)
3 => string 'superGetMethodList' (length=18)
array
'publicValue' => string 'サブクラスのパブリックプロパティ' (length=48)
'protectedValue' => string 'サブクラスのプロテクティッドプロパティ' (length=57)
'privateValue' => string 'スーパークラスのプライベートプロパティ' (length=57)
------------------------------------------------------------------------------------------------
array
0 => string 'subGetMethodList' (length=16)
1 => string 'superPublicMethod' (length=17)
2 => string 'superProtectedMethod' (length=20)
3 => string 'superPrivateMethod' (length=18)
4 => string 'superGetMethodList' (length=18)
array
'publicValue' => string 'サブクラスのパブリックプロパティ' (length=48)
'protectedValue' => string 'サブクラスのプロテクティッドプロパティ' (length=57)
'privateValue' => string 'スーパークラスのプライベートプロパティ' (length=57)
------------------------------------------------------------------------------------------------
と上記のようなコードを描いてしらべたところなんとか把握できました。
どうやらあちこちのサイトで描かれているサブクラスはスーパークラスのpublicおよびprotectedのメンバが継承されるという
記述を数多くみてきたせいで、サブクラスにはスーパークラスのprivateはいっさい継承されないものとおもっていました。
だから、サブクラスからスーパークラスのprivateなメンバにアクセスできるのが謎だったんですね。これはマニュアルもちょっと記述の仕方を考えてほしいなとおもったところです。
No.1
- 回答日時:
えーとそういう事です・・・
あくまで$obj->testMethod01() はpublicメソッドへのアクセスなので問題はないです。
クラスの外側
$obj = new ExClass();
$obj-> testMethod01();
ここから見える(アクセスできる)かどうかです。
testMethod01からは「同じクラス内」のメンバ変数にアクセスできるので、そのような状態になります。
testMethod01がgetterだと思えば分かりやすいかと。
(より混乱されるようでしたらこれは忘れてください)
この回答への補足
え-と
>$obj = new ExClass();
>$obj-> testMethod01();
>ここから見える(アクセスできる)かどうかです。
というのは、スーパ-クラスを継承したExClassというサブクラスから継承元までさかのぼってという意味でしょうか?
以下メソッドは、スーパークラスで定義してサブクラスに継承されたクラスですよね。
クラス定義自体は省略します。
public function testMethod01 () {
print "スーパークラスのパブリックメソッド";
print "<h1>{$this->value01}</h1>";
}
>$obj-> testMethod01();
上の継承したメソッドtestMethod01()を実行している時点でExClassのインスタンスだけど
実際はスーパ-クラス内に入りこんでTestClass(スーパクラス)として振る舞っているということでしょうか?
また、このtestMethod01というメソッドと全く同じ内容でサブクラスでオーバーライドした場合は上記とは異なる動きになりますよね?
オーバ-ロードした場合、サブクラス内で【$this->value01】というプロパティを探す動きにかわるとおもいますが、
オーバ-ロードした場合は完全に、サブクラスとして振る舞うというような解釈でしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) pythonのプログラムについての質問です。 1 2023/05/26 10:31
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Java インスタンス ダウンキャストについて以下の解釈であっているか教えて欲しいです。 サブクラスをスーパー 1 2022/03/27 18:53
- Access(アクセス) Vba Userformを前面に出すについて 3 2022/04/15 12:29
- Visual Basic(VBA) VBA。複数のChangeイベントをまとめる方法 2 2022/03/31 12:03
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
- Access(アクセス) こんにちは。Accessのことで教えてください。M365環境で、Private Declare Fu 1 2023/01/09 14:59
- Visual Basic(VBA) ユーザーフォームに2つのコンボボックス銀行名「ConboBox1」支店名を「ConboBox2」とし 4 2022/08/03 17:34
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「クラス関数」「メンバ関数」...
-
phpのクラスメソッドの定義が長...
-
ラッパークラスって何ですか?
-
php、可変プロパティ名について
-
phpのクラスにて別ファイルの変...
-
いいかげんxamppなんとかしたい...
-
フォントの色を変えるには?
-
onedrive にexcelファイルをア...
-
<大至急!>ご教授願います。
-
メレンゲの歴史
-
PHPのif文でその処理を途中で抜...
-
VBSの「MsgBox」について
-
こちらはただの直列処理ですか?
-
トランザクションが原因?DBに...
-
リンク先を隠す方法はないでし...
-
FTPコマンドでディレクトリごと...
-
CFileDialogの最初のディレクト...
-
PHPでネットワークドライブのop...
-
smartyでホームページ上の画像...
-
コマンドプロンプト エラー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「クラス関数」「メンバ関数」...
-
phpのクラスメソッドの定義が長...
-
ラッパークラスって何ですか?
-
'_'(アンダースコア)の使い方...
-
class定義のphpをファイル分割...
-
配列とオブジェクトの違い
-
PHP4、PHP5 1ファイル複数クラ...
-
関数定義の関数名の前にある&(...
-
php、可変プロパティ名について
-
クラス設計の良い参考書を教え...
-
phpのクラスにて別ファイルの変...
-
class.upload.phpの戻り値(返...
-
【PHP】クラス と 関数 の違い
-
php インスタンスとオブジェク...
-
Re: Cookieを使ってオブジェク...
-
PHPでサブクラスからスーパクラ...
-
クラス
-
onedrive にexcelファイルをア...
-
フォントの色を変えるには?
-
index.phpに入るには、どうすれ...
おすすめ情報