본문 바로가기
언어 정리/C# 개념 및 lib

참조자, static method, 오버라이딩, 오버로드

by 알 수 없는 사용자 2024. 1. 9.

설명할 내용

1. 참조자

2. class 에서의 정적(static)메서드 및 인스턴스 메서드

3. 오버라이딩

4. 오버로드 [ 생성자, 메서드 ]

 


1. 참조자

 

C# 에선 & 대신 ref를 쓴다.
참조자랑 동일한 기능

using System;

class Program
{
    int Swap_x = 0;
    int Swap_y = 0;

    // Swap 메서드는 인스턴스 메서드로 유지
    public void Swap(ref int x, ref int y)
    {
        Swap_x = x;
        Swap_y = y;
    }

    // Main 메서드를 static으로 선언
    static void Main()
    {
        Program p = new Program(); // Program 클래스의 인스턴스 생성

        int i = 1, j = 2;
        p.Swap(ref i, ref j); // 인스턴스를 통해 Swap 메서드 호출
        Console.WriteLine($"{p.Swap_x} {p.Swap_y}");    // "2 1"

        i = 99;
        j = 222;
        p.Swap(ref i, ref j); // 인스턴스를 통해 Swap 메서드 호출
        Console.WriteLine($"{p.Swap_x} {p.Swap_y}");    // "222 99"
    }
}

 

 


2. class 에서의 정적(static)메서드 및 인스턴스 메서드

 

 

Class 내부에서 variable area( class 변수 선언구간 ) 에서 

static 메서드는 static 으로 선언된 변수만 접근이 가능하다.

반대로 instance 메서드는 static + instance 변수 둘다 접근이 가능

생성자에서도 둘다 접근

 

 

using System;

class Entity
{
    static int s_nextSerialNo;
    int _serialNo;
    
    public Entity()
    {
        _serialNo = s_nextSerialNo++;
    }
    
    public int GetSerialNo()
    {
        return _serialNo;
    }
    
    public static int GetNextSerialNo()
    {
        return s_nextSerialNo;
        // return _serialNo; <- 이렇게 static member 함수에서 static member variable 이 아닌 member variable은 접근이 불가능하다
    }
    
    public static void SetNextSerialNo(int value)
    {
        s_nextSerialNo = value;
    }
    
    static void Main()
    {
        Entity.SetNextSerialNo(1000);
        Entity e1 = new Entity();
        Entity e2 = new Entity();
        Console.WriteLine(e1.GetSerialNo());          // Outputs "1000"
        Console.WriteLine(e2.GetSerialNo());          // Outputs "1001"
        Console.WriteLine(Entity.GetNextSerialNo());  // Outputs "1002"
    }
}

 

 

 


3. 오버라이딩

코드 설명 : 
사용할 수식을 정하고, 해당 수식의 변수값 x,y, ... 에 값을 대입해 계산하는 기능을 합니다.

 

using System;
using System.Collections.Generic;

class Program
{
    public abstract class Expression
    {
        public abstract double Evaluate(Dictionary<string, object> vars);
    }

    public class Constant : Expression
    {
        double _value;

        public Constant(double value)
        {
            _value = value;
        }

        public override double Evaluate(Dictionary<string, object> vars)
        {
            return _value;
        }
    }

    public class VariableReference : Expression
    {
        string _name;

        public VariableReference(string name)
        {
            _name = name;
        }

        public override double Evaluate(Dictionary<string, object> vars)
        {
            object value = vars[_name] ?? throw new Exception($"Unknown variable: {_name}");
            return Convert.ToDouble(value);
        }
    }

    public class Operation : Expression
    {
        Expression _left;
        char _op;
        Expression _right;

        public Operation(Expression left, char op, Expression right)
        {
            _left = left;
            _op = op;
            _right = right;
        }

        public override double Evaluate(Dictionary<string, object> vars)
        {
            double x = _left.Evaluate(vars);
            double y = _right.Evaluate(vars);
            switch (_op)
            {
                case '+': return x + y;
                case '-': return x - y;
                case '*': return x * y;
                case '/': return x / y;

                default: throw new Exception("Unknown operator");
            }
        }
    }

    // Main 메서드를 static으로 선언
    static void Main()
    {
        Expression e = new Operation(    // 'x' '*' new Operation
            new VariableReference("x"),
            '*',
        new Operation(                   //  'y' '+' '2'
                new VariableReference("y"),
                '+',
                new Constant(2)
            )
        );
        //// 초기값을 지정해서 dictionary 생성하는 방법
        // Dictionary<string, object> vars = new Dictionary<string, object>
        // {
        //     {"key1", "value1"},
        //     {"key2", 123}
        // };

        Dictionary<string, object> vars = new Dictionary<string, object>();  // 
        vars["x"] = 3;
        vars["y"] = 5;
        Console.WriteLine(e.Evaluate(vars)); // "21"
        vars["x"] = 1.5;
        vars["y"] = 9;
        Console.WriteLine(e.Evaluate(vars)); // "16.5"
    }
}

 

 


4. 오버로드 [ 생성자, 메서드 ]

 

using System;
using System.Collections.Generic;


class OverloadingExample
{
    public int x,y;
    
    // 생성자 오버로딩
    public OverloadingExample(int param_x, int param_y)
    {
        Console.WriteLine("class 생성자 호출 1111");
        (x, y) = (param_x, param_y);
    }
    public OverloadingExample(int param_x)
    {
        Console.WriteLine("class 생성자 호출 2222");
        x = param_x;
        y = 0;
    }
    public OverloadingExample()
    {
        Console.WriteLine("class 생성자 호출 3333");
        x = 0;
        y = 0;
    }
    
    // 스태틱 메서드 오버로딩
    static void F() => Console.WriteLine("F()");
    static void F(object x) => Console.WriteLine("F(object)");
    static void F(int x) => Console.WriteLine("F(int)");
    static void F(double x) => Console.WriteLine("F(double)");
    static void F<T>(T x) => Console.WriteLine($"F<T>(T), T is {typeof(T)}");            
    static void F(double x, double y) => Console.WriteLine("F(double, double)");
    
    public static void UsageExample()
    {
        F();            // Invokes F()
        F(1);           // Invokes F(int)
        F(1.0);         // Invokes F(double)
        F("abc");       // Invokes F<T>(T), T is System.String
        F((double)1);   // Invokes F(double)
        F((object)1);   // Invokes F(object)
        F<int>(1);      // Invokes F<T>(T), T is System.Int32
        F(1, 1);        // Invokes F(double, double)
    }
    static void Main()
    {
        var ins_1 = new OverloadingExample(1,3);
        Console.WriteLine($"ins member var : {ins_1.x}, {ins_1.y}");
        var ins_2 = new OverloadingExample(1);
        Console.WriteLine($"ins member var : {ins_2.x}, {ins_2.y}");
        var ins_3 = new OverloadingExample();
        Console.WriteLine($"ins member var : {ins_3.x}, {ins_3.y}");
        
        UsageExample();        
    }
}

 

 


 

 

댓글