2017-12-15 13 views
1

Liskov 원리를 설명하기 위해 노력하고 있는데, 아래 예제에서 sqaure에 너비를 설정하면 자동으로 동일한 길이로 설정되며 반대의 경우도 마찬가지입니다. 그러나 영역은 0으로 반환됩니다. 두 번째 경우에는 4x4 = 16 및 5x5 = 25가 필요합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 기본 클래스의 속성을 재정의하는 방법에 있다고 생각합니다.유명한 Square/Rectangle 예제의 Liskov 원리가 논리적 인 오류를 낸다

using System; 

public class Rectangle 
{ 

    public int length { get; set; } 
    public int breadth { get; set; } 

    public int area() 
    { 
     return length * breadth; 
    } 

} 

public class Square : Rectangle { 


    public new int length; 
    public new int breadth; 

    public new int Length 
    { 
     get 
     { 
      return this.length; 
     } 
     set 
     { 
      this.breadth = this.length = value; 
     } 
    } 


    public new int Breadth 
    { 
     get 
     { 
      return this.breadth; 
     } 
     set 
     { 
      this.breadth = this.length = value; 
     } 
    } 
} 


public class Program 
{ 

    public static void Main() 
    { 

     Square s = new Square(); 
     s.length = 4; 
     s.breadth = 5; 
     int xx = s.area(); 
     Console.Write(xx); 

     s.length = 5; 
     s.breadth = 4; 
     xx = s.area(); 
     Console.Write(xx); 

    } 



} 
+3

왜 기본 클래스 속성을 숨기고 있습니까? – Mahmoud

+0

어떻게 그들을 숨길 수 있습니까? 모두 공개 되니? 설명 해주십시오? –

+2

'new'는'override'가 아닙니다. 당신은 숨기고 오버라이드하지 않습니다. – Blorgbeard

답변

3

당신이 base class에서 상속 할 때, 당신은 그것의 PublicProtected 모든 멤버를 상속합니다. 동일한 이름을 가진 derived 클래스에 새 멤버를 선언 할 때. 컴파일러는 당신이 그 멤버를 숨길 의도가 있다고 경고하는 경고를 줄 것입니다. new 키워드를 사용하면 컴파일러에게 다음과 같이 말했습니다. 예,이 멤버를 숨기고 싶습니다. area 메서드를 구현하면 base 클래스 properties이 사용되므로 공개되지 않습니다. Fields 그런 이유로 0을 얻습니다. 그래서 코드가 될 것이다 :

당신이 override 뭔가하려는 경우
public class Rectangle 
{ 
    protected int _length; 
    protected int _breadth; 
    public virtual int Length 
    { 
     get { return _length; } 
     set { _length = value; } 
    } 
    public virtual int Breadth { 
     get { return _breadth; } 
     set { _breadth = value; } 
    } 

    public int Area() 
    { 
     return Length * Breadth; 
    } 

} 

public class Square : Rectangle 
{ 

    public override int Breadth 
    { 
     get { return _breadth; } 
     set { _breadth = value; 
      _length = _breadth; 
     } 
    } 
    public override int Length { 
     get { return _length; } 
     set { _length = value; 
      _breadth = _length; 
     } 
    } 
} 

, 그 thingbase 클래스 정의에 virtual 키워드를 추가해야합니다. 예에서 StackOverFlow 예외가 발생합니다. 각 속성 setter가 다른 속성을 호출하기 때문입니다. 그래서이 일이 일어나지 않도록 보호 된 멤버를 사용했습니다. This은 상속에 대한 좋은 참고 자료입니다.

+0

감사합니다. Mahmoud는 가상 재정의로 작업했습니다. –

+0

당신은이 답변에 잘못이 있다고 생각하는 사람에게 투표하려면 누구에게 투표하고 싶습니다. – Mahmoud

+1

@Mahmoud 나는 단지 추측 할 수있을 정도로 나는 downvoter가 아니다. 제 추측은 당신의 예제가 정확하게 이것을하는 법을 보여주지 않는다는 것입니다 - 실제로 질문과 같은 방식으로 보여줍니다. 이 예제를 올바르게 업데이트하여 올바르게 수행하는 방법을 보여줍니다. – xxbbcc