2014-04-24 3 views
0

방금 ​​C#을 배우기 시작했고 캡슐화에 문제가 있습니다. 책에는 응용 프로그램을 작성하는 연습이 있습니다. 실제로 그 내용이 중요하지 않습니다. 를 Form1 :Book Head First C# - 캡슐화에 대한 장을 통과 할 수 없습니다.

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     Farmer farmer; 

     public Form1() 
     { 
      InitializeComponent(); 
      farmer = new Farmer(15, 30); 
     } 

     private void calculateButton_Click(object sender, EventArgs e) 
     { 
      Console.WriteLine("I need {0} bags of feed for {1} cows.", farmer.BagsOfFeed, farmer.NumberOfCows); 
     } 

     private void cowCount_ValueChanged(object sender, EventArgs e) 
     { 
      farmer.NumberOfCows = (int)cowCount.Value; 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      farmer.BagsOfFeed = 5; 
     } 
    } 
} 

그리고 클래스 농부 :

namespace WindowsFormsApplication1 
{ 
    class Farmer 
    { 
     public int BagsOfFeed; 

     private int feedMultiplier; 
     public int FeedMultiplier { get { return feedMultiplier; } } 

     private int numberOfCows; 
     public int NumberOfCows 
     { 
      get 
      { 
       return numberOfCows; 
      } 
      set 
      { 
       numberOfCows = value; 
       BagsOfFeed = FeedMultiplier * numberOfCows; 
      } 
     } 

     public Farmer(int numberOfCows, int feedMultiplier) 
     { 
      this.feedMultiplier = feedMultiplier; 
      NumberOfCows = numberOfCows; 
     } 

    } 
} 

때문에 응용 프로그램이 제대로 작동하지 않습니다 Form1 클래스의를 Button1_Click 방법의

나는 2 개 종류가있다. 책에서 내가 속성에 공공 BagsOfFeed 필드를 변경해야한다고 쓰여 - 그래서 나는 수행

public int BagsOfFeed { get; set; } 

을 그리고 텍스트는 그 후 거기 :

Now you’ve got a property instead of a field. When C# sees this, it works exactly the same as if you had used a backing field (like the private numberOfCowsbehind the public NumberOfCowsproperty).

That hasn’t fixed our problem yet. But there’s an easy fix—just make it a read-only property: Try to rebuild your code—you’ll get an error on the line in the button that sets BagsOfFeedtelling you that the set accessor is inaccessible. You can’t modify BagsOfFeedfrom outside the Farmerclass—you’ll need to remove that line in order to get your code to compile, so remove the button andits event handlerfrom the form. Now your Farmerclass is better encapsulated!

그리고 난 정말 무슨 일이 일어나고 있는지 이해가 안 돼요 - 내 응용 프로그램은 이전과 동일하게 작동합니다. 내가 어떻게 든이 속성을 읽기 전용 속성으로 만들어야한다고 생각하는데,이 텍스트에서는 (설명하지는 않았지만) 말한 것입니다. 그러나 어떻게? 나는 구현의 설정 부분을 지우려고했는데, 그때 나는 오류가 있습니다

Error 1 'WindowsFormsApplication1.Farmer.BagsOfFeed.get' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors. C:\Users\Dess\documents\visual studio 2013\Projects\HeadFirst\WindowsFormsApplication1\Farmer.cs 12 33 ExerciseCowCount

을 내가 하나 개의 추가 질문이 - public int Variablepublic int Variable{get;set;} 같은 일반 필드의 차이점은 무엇입니까?

+0

같은 방법을 구현하기위한 필요성을 생략 :'공공 INT의 var' 공공 필드 (나쁜!) 그리고'public int var {get; set;}'은 프로퍼티입니다 –

+0

하나는 필드이고 다른 하나는 프로퍼티입니다.하지만 여전히 똑같은 방법으로 그것들에 접근 할 수 있습니다. 그렇다면 어떻게 사용해야합니까? 그리고 왜? – Dess

+1

일반 지침은 프로그램의 어느 곳에서나 변경할 수 있으므로 공개 필드를 사용하지 않는 것이 좋습니다. 속성을 사용하여 캡슐화하십시오. 속성을 '읽기 전용'으로 만들고 싶다면'public int variable {get; 개인 집합;}'. 이 방법은 어디서나'get' 할 수 있지만 클래스 내부에서만'set' 할 수 있습니다. –

답변

2

그리고 실제로 어떤 일이 일어나고 있는지 이해하지 못합니다. 제 신청서는 이전과 동일하게 작동합니다.

다르게. 먼저 프로그램에서 어디서나 액세스하고 변경할 수있는 클래스에 public int BagsOfFeed을 가지고있었습니다.

이 작동합니다 :

farmer.BagsOfFeed= 1; 
int i = farmer.BagsOfFeed; // i is now 1 
farmer.BagsOfFeed= 5; 
i = farmer.BagsOfFeed; // i is now 5 

일반 가이드 라인은 그러나 그들이 프로그램에서 어디에서 변경 될 수 있습니다 때문에 공공 필드를 사용하지 않는 것입니다. 상황이 있습니다 (책이 적어도 1 가지 예를 들어 설명하고 있음을 알고 있습니다. 올바르게 회상하면 파티 비용을 계산하는 방법에 대해 설명합니다). 프로그램의 출력이 엉망이 될 수 있습니다.

우리는 필드를 캡슐화하기 위해 속성을 사용합니다.

public int BagsOfFeed 
{ 
    get; 
    private set; 
} 

주에게 privateset 전에 : 당신이해야 할 의미가 무엇

That hasn’t fixed our problem yet. But there’s an easy fix—just make it a read-only property: Try to rebuild your code—you’ll get an error on the line in the button that sets BagsOfFeedtelling you that the set accessor is inaccessible. You can’t modify BagsOfFeedfrom outside the Farmerclass .

는 속성이 읽기 전용으로 만들 수 있습니다. 이것이하는 일은 속성을 만들어 어디서나 얻을 수 있지만 그 클래스 내부에서만 설정할 수 있습니다. BagsOfFeed가 캡슐화되었습니다. 이 특정 예에서

이 속성은 마지막 질문에 대답하기 farmer.getBagsOfFeed()farmer.setBagsOfFeed(n)

+1

'BagsOfFeed'는'NumberOfCows' 대신에 읽기 전용 속성으로 변환해야합니까? – MAV

+0

좋은 지점, 나는 그것을 편집 할 것이다 –

+0

위대한. 고마워, 지금 나는 그것을 얻는다 :) – Dess