'Class'에 해당되는 글 2건

  1. 2020.06.28 [C#] 다른 파일, 다른 클래스 값/함수 사용 1
  2. 2020.06.08 [C#] Class, 클래스, 구조체

C언어만 사용하던 나는 솔직히 OOP 개념이 익숙하거나 크게 와 닿지 않는다.

 

중복된 기능의 함수나 DB Handler, Logger 등의 기능 단위를 구분할 수 있는 것들을 모듈화하여

Library 형태로 만들어 컴파일 할 때 추가하여 사용하곤 했다. 

 

C#에서는 하나의 프로젝트 안에 여러 클래스를 생성하여 사용하는 것 같으니 방법을 정리해 보자.

 

delegate 테스트했던 프로젝트에 추가해서 진행하면 좋을것 같다.

2020/06/20 - [C#] - [C#] delegate, 폼 간의 DATA 공유

[C#] delegate, 폼 간의 DATA 공유

Trading 시스템을 내가 아닌 제 3자의 사용자적 입장에서 사용하도록 시뮬레이션 해 보았을 때 자식 Form을 새로 띄워서 값을 입력 받거나 확인할 수 있게 하는 작업이 많이 필요하단 것을 알게 되��

brandon-dev.tistory.com

Form2에서 입력했던 '아이디'와 '비밀번호'를 Form1에서 바로 출력하지 않고

새로운 클래스 파일(.cs)의 객체에 저장한 후에 그 값을 읽어와서 출력하는 방법으로 진행해 보자.

 

오른쪽 솔루션 탐색기에서 프로젝트 명의 오른쪽 클릭 후 [ 추가(D) ] - [ 새 항목(W) ]을 선택한다.

 

 

프로젝트 오른쪽 클릭 - [ 추가(D) ] - [ 새 항목(W) ]

 

 

클래스를 선택 후에 입력할 사용자 정보를 관리할 'User_Info.cs' 파일을 추가한다.

 

 

User_Info.cs 파일 추가

 

User_Info Class는 ID와 Password, 두 개의 변수를 갖고, 각각의 값을 Set/Get하는 함수를 갖게 될 것이다.

 

ID와 비밀번호는 사용하는 Class에서 직접 접근할 수 없도록 'private' 접근 제한자를 사용하고, 각각의 값을 Handling 할 수 있는 'public' 함수를 만들어 사용할 수 있도록 한다. (이게 객체지향 방법이라는데...나는 익숙치 않아서....Anyway)

 

[ User_Info.cs ]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace delegate_test
{
    class User_Info
    {
        private string Id;             // 사용자 ID
        private string Password;       // 사용자 비밀번호

        // 생성자
        public User_Info()
        {
            Id = string.Empty;
            Password = string.Empty;
        }

        public void SetId(string Id)
        {
            this.Id = Id;
        }

        public string GetId()
        {
            return this.Id;
        }

        public void SetPassword(string Password)
        {
            this.Password = Password;
        }

        public string GetPassword()
        {
            return this.Password;
        }
    }
}

참고로 나는 변수의 초기화를 굉~~장히 중요하게 생각하는 개발자다. (생성자에서 변수 초기화는 무조건 필수!!)

 

이제 User_Info Class를 어떻게 사용하는가...

두 가지의 방법이 있는데, 하나는 User_Info Class 내에 static 객체를 하나 생성해두고 다른 곳에서 호출해서 쓰는 방식이고 다른 하나는 User_Info Class를 사용할 곳에서 객체를 직접 생성해서 사용하는 방식이 있다. 

 

< 방법 1> - Static 객체

[User_Info.cs]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace delegate_test
{
    class User_Info
    {
        // static 객체
        public static User_Info gUser_Info = new User_Info();

        private string Id;             // 사용자 ID
        private string Password;       // 사용자 비밀번호

        // 생성자
        public User_Info()
        {
            Id = string.Empty;
            Password = string.Empty;
        }

        public void SetId(string Id)
        {
            this.Id = Id;
        }

        public string GetId()
        {
            return this.Id;
        }

        public void SetPassword(string Password)
        {
            this.Password = Password;
        }

        public string GetPassword()
        {
            return this.Password;
        }
    }
}

어디서든 접근 가능하도록 public으로 만든 static 객체를 만들어 둔다.

 

사용하는 방법은 간단하다.

User_Info 객체를 사용하고 싶은 곳에서 [클래스명].[객체명].[함수/변수]와 같은 형태로 사용하면 된다.

[Form1.cs]

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace delegate_test
{
    public delegate void LoginGetEventHandler(string id, string password); // 자식 Form EventHandler

    public partial class Form1 : Form
    {
        static string static_id = "brandon";
        Form2 Child = new Form2(static_id);

        public Form1()
        {
            InitializeComponent();
            Form2.LoginGetEvent += new LoginGetEventHandler(this.Login_Process); // EventHandler 등록
        }

        private void 로그인ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Child.Owner = this;
            Child.ShowDialog();                     
        }

        private void Login_Process(string id, string password) // Event 발생 시, 처리할 함수 선언
        {
            // User_Info 객체에 입력 받은 정보 저장
            User_Info.gUser_Info.SetId(id);
            User_Info.gUser_Info.SetPassword(password);


            // User_Info 객체에서 값 가져오기
            string test_result = string.Empty;
            //test_result = String.Format("ID : {0}, PW : {1}", id, password);
            test_result = String.Format("ID : {0}, PW : {1}", User_Info.gUser_Info.GetId(), User_Info.gUser_Info.GetPassword())
            textBox1.Text = test_result;  // 자식 Form에서 수신한 값 표시
        }
    }
}

 

이전과 동일하게 비밀번호를 'asdf1234!@#$'로 입력 후 로그인 버튼 클릭

 

전과 동일하게 아이디랑 비밀번호가 출력되면 정상적으로 User_Info Class를 사용하는 셈.

 

 

자식 Form에서 입력한 값을 부모 Form에서 받아 User_Info 객체에 Set/Get 후 출력 

 

 

사용자 정보의 경우, 프로그램내에서 단 하나만(!) 존재하는 것이기에 위의 예제처럼 static 객체로 선언해서 쓰는것이 좋을 것 같다. 상황에 따라 여러개의 객체가 필요한 경우는 아래처럼 사용하면 된다.

 

[Form1.cs]

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace delegate_test
{
    public delegate void LoginGetEventHandler(string id, string password); // 자식 Form EventHandler

    public partial class Form1 : Form
    {
        // User_Info 객체 생성
        User_Info gUser_Info = new User_Info();

        static string static_id = "brandon";
        Form2 Child = new Form2(static_id);

        public Form1()
        {
            InitializeComponent();
            Form2.LoginGetEvent += new LoginGetEventHandler(this.Login_Process); // EventHandler 등록
        }

        private void 로그인ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Child.Owner = this;
            Child.ShowDialog();                     
        }

        private void Login_Process(string id, string password) // Event 발생 시, 처리할 함수 선언
        {
            // User_Info 객체에 입력 받은 정보 저장
            gUser_Info.SetId(id);
            gUser_Info.SetPassword(password);


            // User_Info 객체에서 값 가져오기
            string test_result = string.Empty;
            //test_result = String.Format("ID : {0}, PW : {1}", id, password);
            test_result = String.Format("ID : {0}, PW : {1}", gUser_Info.GetId(), gUser_Info.GetPassword());
            textBox1.Text = test_result;  // 자식 Form에서 수신한 값 표시
        }
    }
}

 

Posted by [ 브랜든 ]
,

Class...객체지향에서 빼놓을 수 없는.

Class에는 항상 상속, 오버로딩, 오버라이딩 그리고 캡슐화가 항상 붙어 다닌다.

 

절차적 언어인 C언어를 주 언어로 사용하던 나는

솔직히 객체지향 방식이 쉽게 와닿지 않았다. (사실은 지금도 그렇다....)

그래서 Python을 써도 C언어를 주로 쓰던 시절처럼 Library 함수 형태로 만드는 것이 익숙하고

Class 형식의 Library를 만드는 것이 덜 익숙하다. 

 

그래도 Class에 대해 정리를 해두면 필요할 경우 곧잘 사용할 수 있겠지. 

 

C언어를 사용하던 나에게는 구조체(Struct)라는 개념은 아주 많이 익숙하다. 

때때로 C# 책을 만든 저자들은 클래스와 구조체를 크게 구분하지 않으려 하지만 나와 같은 개발자에게는

분명하게 개념상의 차이점이 있다. 

 

  • 클래스 및 구조체에는 데이터와 동작을 나타내는 멤버가 있다. (사실 8년여간 C 프로그래밍을 해오면서 단 한번도 구조체 않에 멤버 함수를 선언해서 사용해 본 적이 없다!!)
  • 클래스가 상속 받았다면, 클래스에서 선언된 모든 멤버와 함께 상속받은 클래스에서 선언된 모든 멤버들(생성자 및 소멸자 제외)도 클래스의 멤버에 포함된다.
멤버 설명
필드 필드는 클래스 또는 구조체에서 직접 선언되는 모든 형식의 변수이다. 필드는 기본 제공 형식 또는 다른 클래스의 인스턴스일 수 있다.
상수 상수는 값이 컴파일 시간에 설정되며, 변경할 수 없는 필드나 속성이다.
속성 해당 클래스의 필드처럼 액세스되는 클래스의 메소드로 객체 모르게 필드가 변경되지 않도록 할 수 있다.
메소드 클레스가 수행하는 작업을 정의한다. 입력으로 매개변수를 사용할 수 있고, 매개변수를 통해 출력 데이터를 반환할 수 있다. 매개변수를 통하지 않고 직접 값을 반환할 수도 있다.
이벤트 이벤트는 버튼 클릭, 성공적인 메소드 완료 등의 사건이 발생했을 때 알림을 다른 객체에 제공한다.
이벤트는 대리자(delegate)를 사용하여 정의 및 트리거 된다.
연산자 오버로드 된 연산자는 클래스 멤버로 간주되며, 클래스에서 'public static' 메소드로 정의한다.
인덱서 인덱서를 사용하면 배열과 유사한 방식으로 객체를 인덱싱할 수 있다. 
생성자 생성자는 객체를 처음 만들 때 호출되는 메소드이다. 보통 객체의 데이터를 초기화하는데 사용한다.
소멸자 C#에서 드물에 사용되며, 메모리에서 객체를 제고할 때 런타임 실행 엔진이 호출하는 메소드이다.

 

C# 공부를 위해 구매한 책에서 발췌한 내용이다. 

다른 것들은 한번쯤은 들어보거나 사용해봤던 것들인데, '이벤트'와 '인덱서'는 조금 새롭다. 

 

C 언어로 프로그래밍 할 때 '구조체 배열'을 자주 사용했었는데, '인덱서'를 사용하면 비슷한 기능을 구현할 수 있을 것 같다. 

'이벤트' 요소는 .NET 계열에서 특화적으로 사용되는 것으로 생각되는데(그냥 내 생각....), 내가 구현하고자 하는 Trading System에서 아주 많이 사용될 기능으로 보인다. 

 

  1. 필드 (Field)
  • 인스턴스(객체) 필드 : 객체 이름과 함께 사용. public string name과 같이 [접근제한자][자료형][필드명]으로 생성하고 [인스턴스].[필드명]으로 사용.
  • 정적(클래스) 필드 : 클래스 이름과 함께 사용. static 키워드 필수. [클래스이름].[필드명]
  1. 상수
  • 컴파일 시간에 알려진 변경할 수 없는 값. 프로그램 수행되는 공안 갑승ㄹ 변경하지 않는 경우 사용.
  • const 한정자 사용.
  • bool, byte, char, int double, string만 const 사용 가능.
  • Access : [클래스이름].[상수명]

 

 

Posted by [ 브랜든 ]
,