2009-06-27 11 views
2

私は一般的なOOP質問があります。C#とPHP OOPの違い

私はC#

class Parent 
{ 
    public string val = "Parent"; 

    public void getValue() 
    { 
     Console.WriteLine(this.val); 
    } 
} 

class Child:Parent 
{ 
    public string val = "Child"; 
} 

Child child = new Child(); 
child.getValue(); 

コード出力 '親' で、次のクラスを持っている場合。これはParentオブジェクトを指しているからです

私はPHP5で同じことを行う場合は、次の

class ParentClass { 
public $val = 'parent'; 

    public function foo() 
    { 
     echo $this->val; 
    } 
} 

class ChildClass extends ParentClass { 
public $val = 'child'; 
} 

$a = new ChildClass(); 
$a->foo(); 

結果が '子' になります。

私は

private $val = 'parent'; 

public $val = 'parent'; 

を変更した場合、その後PHPにも '親' が表示されますけど。 C#は常にパブリックとプライベートの両方のアクセス修飾子を持つ 'parent'を返します。

このため、何らかの理由はありますか?そして、どのような動作が正しいですか?

読むために任意の有用なリンクが高く評価されます!

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

+1

あなたが派生クラスの変数に「新しい」キーワードを使用しない限り、C#はそのコードについて警告することに注意してください。 –

答えて

6

あなたの規定のシナリオには正しいか間違った動作はありません。言語設計者は、それらに意味をなさないものを行いました。 GetValueメソッドは、「これは」親valを意味し、親クラスで呼び出されているので、あなたがC#で期待される動作を得ることはありません

理由があります。

正しい動作を得るために、あなたはoverrideキーワードで、子クラスで同じメソッドが含まれます:

public class Child 
{ 
    public string val = "Child"; 
    public override void GetValue() 
    { 
     Console.WriteLine(val); 
    } 
} 

...コンソールに「子」を印刷します。

+0

言われているように、PHPの振る舞いはもっと分かりやすいでしょう...結局のところ、変数をオーバーライドするとどうなりますか。 – Sampson

+3

C#では、変数を上書き可能としてマークし、上書きすることを明示的に指定する必要がある変数を上書きすることができます。それは、ベースクラスに、それに対する変更をより詳細に制御できるようにします。 –

2

私はそれをオーバーライドまたは他のOOP言語に存在する仮想修飾子を使用していないので、PHP OOPがこのように動作していると思います。私の推測は、それはPHPの仕組みの限界か、簡単に避けることができるものを書くのに時間がかかりすぎるということでしょう。

class Parent 
{ 
    // Public identifiers cannot be overridden in C# 
    private string _val = "Parent"; 
    // Public properties can. 
    public virtual string val 
    { 
     get { return _val; } 
    } 

    public void getValue() 
    { 
     Console.WriteLine(this.val); 
    } 
} 

class Child : Parent 
{ 
    private string _val = "Child"; 
    public virtual string val 
    { 
     get { return _val; } 
    } 
} 
+0

このコードはコンパイルされません。 エラーCS0106:修飾子 'virtual'はこの項目に無効です –

+0

ええ、そうです。公開識別子を上書きすることはできません。一定。おかげさまで –

+0

未投票。 :-) –

2

PHPの式が実行時まで評価されませんので、それは、派生クラスのオブジェクトを使用することは理にかなって:ここで

は、あなたがC#で同様の結果になるだろう方法です。ただし、C#の式はコンパイル時に評価されます。基本クラス関数は、それがオーバーライドされるかどうか分からないので、それが知っている文字列を参照します。

仮想キーワードは、これが上書きされることを期待するようにコンパイラに伝える機能、ためで出番です。これは、vtableの関数を検索します。しかし、データと同等のものはありません。

ただし、仮想プロパティにすることができますし、期待どおりの動作があります。プロパティは偽装の関数なので、vtableを使用します。

ここにPHP効果を達成するためのコードがあります。

class Parent{  
    public virtual string val 
    { 
     get { return "Parent"; } 
    } 

    public void getValue()  
    {   
     Console.WriteLine(this.val);  
    } 
} 

class Child:Parent 
{ 
    public override string val 
    { 
     get { return "Child"; } 
    } 
}