2009-06-27 5 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(); 

코드 출력 '부모'에서 다음과 같은 클래스가있는 경우. 이 점이 부모 개체를 가리키고 있기 때문에 이해합니다. 맞습니까?

내가 PHP5에서 동일한 작업을 수행하는 경우 :

class ParentClass { 
public $val = 'parent'; 

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

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

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

결과는 '아이'일 것이다.

비록을 그때 PHP는 '부모'가 표시됩니다

private $val = 'parent'; 

public $val = 'parent'; 

를 변경하는 경우. C#은 항상 공개 및 개인 액세스 수정자를 모두 '부모'로 반환합니다.

어떤 이유가 있습니까? 그리고 어떤 행동이 맞습니까?

유용한 링크를 읽으시 길 바랍니다.

감사합니다.

+1

파생 클래스의 변수에 'new'키워드를 사용하지 않으면 C#에서 해당 코드에 대해 경고합니다. –

답변

6

명시된 시나리오에서 올바르지 않거나 잘못된 동작이 없습니다. 언어 설계자는 그들에게 의미가있는 것을했습니다.

C#에서 예상되는 동작을 얻지 못하는 이유는 "this"가 부모 val을 의미하는 부모 클래스에서 GetValue가 호출되기 때문입니다.

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

... 콘솔에 "아이"를 인쇄 할 것이다 :

올바른 동작을 얻으려면, 당신은 override 키워드로 자식 클래스에서 같은 방법을 포함한다.

+0

그 말은 PHP의 동작이 더 현명 해 보입니다 ... 결국, 변수를 무시할 때 일어나는 일입니다. – Sampson

+3

C#을 사용하면 변수를 재정의 할 수 있도록 재정의 할 수 있으며 변수를 재정의하려는 것으로 명시 할 수 있습니다. 기본 클래스가 수정할 수있는 기능을 더 많이 제어 할 수 있습니다. –

2

PHP OOP는 다른 OOP 언어에있는 재정의 또는 가상 한정자를 사용하지 않기 때문에 이런 식으로 행동한다고 ​​생각합니다. 내 생각 엔 PHP가 어떻게 작동하는지에 대한 제한이거나 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 : 수정 자 '가상'이이 항목에 유효하지 않습니다. –

+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"; } 
    } 
}