C# 4

C# 2019. 12. 9. 02:05

* 상속


class 기반 클래스

{...}


class 파생 클래스 : 기반 클래스

{...}


- 파생 클래스는 기반 클래스의 모든 것을 물려받는다. private만 빼고

- 생성시 기반 -> 파생 순서로 생성, 소멸은 파생 -> 기반 순서로 소멸



* 파생 클래스에서 기반 클래스의 변수 초기화


   class Program2

    {

        public string name;


        public Program2(string name)

        {

            this.name = name;

        }

    }

    class Program : Program2

    {

        public Program(string name) : base(name)

        {

            Console.WriteLine(name);

        }

        static void Main(string[] args)

        {

            Program a = new Program("abc");

        }

    }


// 파생 클래스의 생성자 : base() 형식으로 기반 클래스의 생성자로 이동

// 기반 클래스부터 수행 후에 파생 클래스 수행



* 기반과 파생 클래스 사이의 형식 변환 그리고 is, as


class Cat : Mammal

{

    public void Meow()

    {

        Console.WriteLine("Meow()");

    }

}

class MainApp

{

    static void Main(string[] args)

    {

        Mammal mammal = new Dog();  // 파생의인스턴스는기반인스턴스로쓸수있다. mammal 객체가dog 형식이다.

        Dog dog;


        if (mammal is Dog)  // mammal 객체가dog 형식인가맞다네그럼bool에서true

        {

            dog = (Dog)mammal;  // 형식변환. (int)a 처럼

            dog.Bark();

        }


        Mammal mammal2 = new Cat();


        Cat cat = mammal2 as Cat  // 형식이맞다면cat에null이아닌값이들어감


            if (cat != null)

            cat.Meow();


        Cat cat2 = mammal as Cat

            if (cat2 != null)

            cat2.Meow();

        else

            Console.WriteLine("cat2 is not a Cat");

    }

}


- is 와 as는 (객체 is 클래스) 또는 (객체 as 클래스) 형태이다.

- is는 true와 false를 반환해서 if문에 쓰면 좋고 as는 null 또는 클래스를 반환함.

- 객체에 클래스가 제대로 들어갔는지 검사하는 용도로 쓰임.



* 기반과 파생 클래스 변환 방법


    class Program2

    {

        public int a = 10;

        public int b = 20;

        public void c (int x)

        {

            Console.Write(x);

        }

    }


    class Program : Program2

    {


        public int x = 11;

        public int y = 22;


        public void z(int zz)

        {

            Console.Write(zz);

        }



        static void Main(string[] args)

        {


            // 기반 <- 파생


            Program2 a = new Program();

            Console.WriteLine("{0} {1}", a.a, a.b);


            // 파생 <- 기반

           

            Program bb = (Program)a;

            Console.WriteLine("{0} {1} {2} {3}", bb.a, bb.b, bb.x, bb.y);


        }

    }


- 객체 하나로 기반과 파생을 바꿔가면서 접근할 수 있다.

- 시작은 기반 <- 파생 형태이다. 기반클래스 객체 = new 파생클래스();  // 반대로 하면 안됨..

- 파생 <- 기반 바꿀 때는 파생클래스 객체 = (파생클래스)객체;



* 오버라이딩을 통한 재정의


class Program3

{

    public virtual void initial()

    {

        Console.WriteLine("aaa");

    }

}


class Program2 : Program3

{

    public override void initial()

    {

        base.initial();

        Console.WriteLine("bbb");

    }

}



class Program : Program3

{

    public override void initial()

    {

        base.initial();  // 오버라이딩 된 곳에서 기반 접근할 때

        Console.WriteLine("ccc");

    }


    static void Main(string[] args)

    {


        Program a = new Program();

        a.initial();

    }

}


// 기반 클래스에 메소드 하나를 추가함. virtual로 말이다.

// 파생 클래스에는 같은 이름의 메소드를 만들면서 override로 사용한다.

// 같은 이름의 메소드를 파생 클래스에서 사용할 수 있다.

// 기반 클래스에 바로 접근할 수 있는 base. 형태는 파생 클래스의 메소드 안에서 사용할 수 있다.

// private 형태는 상속 받을 수도 없고 오버라이딩 할 수 없다.


- 만약 program3 a = new program() 이라면 a.initial()는 파생에서 출력할까 기반에서 출력할까?

- program3 클래스이므로 당연히 기반에서 출력해야하지만 오버라이딩된 파생에서 출력함.



* new 한정자


    class Base

    {

        public void MyMethod()

        {

            Console.WriteLine("a");

        }

    }


    class Derived : Base

    {

        public new void MyMethod()

        {

            Console.WriteLine("b");

        }

    }


    class MainApp

    {

        static void Main(string[] args)

        {

            Base baseObj = new Base();

            baseObj.MyMethod();  // a


            Derived derivedObj = new Derived();

            derivedObj.MyMethod();  // b


            Base baseOrDerived = new Derived();

            baseOrDerived.MyMethod();  // override 되었다면 b겠지만.. new로 숨겨서 a가 됨.

        }

    }


- 한정자에 new가 들어가면 숨기게 된다.

- 각각 기반, 파생 클래스에 접근하는데는 무리없음.

- 거의 쓸모없음.



* 오버라이딩 봉인


class Base

{

    public virtual void SealMe()

    {

    }

}


class Derived : Base

{

    public sealed override void SealMe()

    {

    }

}


class WantToOverride : Derived

{

    public override void SealMe()

    {

    }

}


class MainApp

{

    static void Main(string[] args)

    {

    }

}


- new 한정자는 override를 빼고 new를 붙였다면 봉인은 sealed를 추가하여 붙임

- 오버라이딩 했지만 뭔가 컴파일 에러등으로 오버라이딩하고 싶지 않을 때 사용

- 여튼 별로 필요없음

'C#' 카테고리의 다른 글

C# 6  (0) 2019.12.09
C# 5  (0) 2019.12.09
C# 3  (0) 2019.12.09
C# 2  (0) 2019.12.02
C# 1  (0) 2019.12.02
블로그 이미지

ryancha9

https://blog.naver.com/7246lsy

,