C#プログラミング08:継承性


継承


クラスは別のクラスから遺産を継承できます(=継承)
支援せずに重傷を負う.
  • 親(クラスベース):継承クラス
  • サブクラス(派生クラス):継承クラス
  • namespace Program {
        public class Person
        {
            public string Gender { get; set; } = "Unknown";
            public string doubleStr (string str)
            {
                return $"{str}{str}";
            }
        }
        public class Student : Person // Person클래스를 상속
        {
            public string Dept { get; set; } = "Unknown";
            public int Grade { get; set; } = 0;
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Person person = new Person()
                {
                    Gender = "female"
                };
                Console.WriteLine(person.Gender); // female
                Console.WriteLine(person.doubleStr(person.Gender)); // femalefemale
    
                Student student = new Student()
                {
                    Gender = "male",
                    Dept = "CE",
                    Grade = 2
                };
                Console.WriteLine(student.Gender); // male
                Console.WriteLine(student.doubleStr(student.Dept)); // CECE
                Console.WriteLine(student.Grade); // 2
            }
        }
    }

    sealedキーワード

    sealedクラス継承を回避するためにキーワードを追加してもよいし、サブクラスでメソッドが上書きされることを防止してもよい.

    継承の制限


    次のコードがsealed設定のクラスを継承しようとしたときにエラーが発生しました.오류 CS0509 'Wonjin': sealed 형식 'Student'에서 파생될 수 없습니다.
    public class Person
    {
        public string Gender { get; set; } = "Unknown";
        public string doubleStr (string str)
        {
            return $"{str}{str}";
        }
    }
    
    public sealed class Student : Person // Person클래스를 상속
    {
        public string Dept { get; set; } = "Unknown";
    }
    
    class Wonjin : Student // <-- 컴파일오류 CS0509
    {
        // something
    }

    仮想メソッドの上書き制限


    次のコードはsealed設定のメソッドを上書きしようとしており、コンパイルエラーが発生します.CS0239 'Wonjin.SaySomething(string)': 상속된 'Student.SaySomething(string)' 멤버는 봉인되어 있으므로 재정의할 수 없습니다.
    class Person
    {
        public string Gender { get; set; } = "Unknown";
        public virtual void SaySomething(string str) { }
    }
    
    class Student : Person // Person클래스를 상속
    {
        public string Dept { get; set; } = "Unknown";
        public sealed override void SaySomething(string str)
        {
            Console.WriteLine(str);
        }
    }
    
    class Wonjin : Student // <-- 컴파일오류 CS0509
    {
        public override void SaySomething(string str)
        {
            Console.WriteLine(str);
            Console.WriteLine(str);
            Console.WriteLine(str);
        }
    }

    親/子のフォーマットの変換

  • 子を親に(暗黙的に変換)
  • 親代入子(明示的な変換):実行時にエラーが発生する可能性があります
  • 暗黙的変換


    暗黙的変換は、方法過負荷の代替案として使用することができる.
    この場合、親の配列は子を要素として使用できます.
    namespace Program {
        class SayMachine {
            public void SayGender(Person obj)
            {
                obj.SaySomething(obj.Gender);
            }
        }
    
        class Person {
            public string Gender { get; set; } = "Unknown";
            public void SaySomething(string str)
            {
                Console.WriteLine(str);
            }
        }
        class Student : Person {
            public string Dept { get; set; } = "CE";
        }
        class Wonjin : Student {
            public string Name { get; set; } = "wonjinLee";
        }
    
        class Program {
            static void Main(string[] args)
            {
                Student student = new Student() { Gender = "female" };
                Wonjin wonjin = new Wonjin() { Gender = "male" };
    
                Person[] persons = new Person[] { student, wonjin };
    
                SayMachine sayMachine = new SayMachine();
                foreach (Person person in persons)
                {
                    sayMachine.SayGender(person);
                    // female
                    // male
                }
            }
        }
    }

    演算子

  • as演算子
    フォーマットコピー演算子と同じ動作ですが、変換に失敗したときに実行時エラーは発生しません.nullをオブジェクト参照に代入します.
  • is演算子
    オブジェクトのフォーマットが正しいかどうかを確認し、true、false
  • を返します.
    class Person {
        public string Gender { get; set; } = "Unknown";
    }
    class Student : Person {
        public string Dept { get; set; } = "Unknown";
    }
    class Wonjin : Student {
        public string Name { get; set; } = "Unknown";
    }
    
    class Program {
        static void Main(string[] args)
        {
            Person person1 = new Person();
            Person person2 = new Student();
            Student student = new Student();
            Wonjin wonjin = new Wonjin();
                
            // as연산자
            student = person1 as Student; // person1객체를 Student클래스로 형변환
            if(student != null) { /* 여긴 올일이없다*/ }
            else {
                Console.WriteLine("student는 null"); // 출력됨
            }
    
            student = person2 as Student; // person2객체를 Student클래스로 형변환
            if (student != null) {
                Console.WriteLine("student는 person2"); // 출력됨
            }
            else { /* 여긴 올일이없다*/ }
    
            // is연산자
            if (person2 is Wonjin) { /* 여긴 올일이없다*/ }
            if (wonjin is Person) {
                Console.WriteLine("wonjin은 Person");  // 출력됨
            }
        }
    }

    親/子作成者、ターミネータ


    サブクラスが作成されている場合は、次の順序で実行します.
    1.親を実行する作成者
    2.サブクラスを実行する作成者
    3.サブクラスのターミネータを実行する
    4.親のターミネータの実行
    class Person {
        public Person (int a)
        {
            Console.WriteLine($"Person 생성자, 매개변수 a = {a}");
        }
        ~Person ()
        {
            Console.WriteLine("Person 종료자");
        }
    }
    class Student : Person {
        public Student(int a, int b) : base(a)
        {
            Console.WriteLine($"Student 생성자, 매개변수 b = {b}");
        }
        ~Student() {
            Console.WriteLine("Student 종료자");
        }
    }
    
    class Program {
        static void Test()
        {
            Student student = new Student(53, 53535353);
        }
        static void Main(string[] args)
        {
            Test();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            /*
            Person 생성자, 매개변수 a = 53
            Student 생성자, 매개변수 b = 53535353
            Student 종료자
            Person 종료자
            */
        }
    }

    object

    objectクラスはすべてのクラスの親です.
    次のコードで示すように、Objectクラスとして定義します.
    public class Object {
        public virtual bool Equals();
        public virtual int GetHashCode();
        public Type GetType();
        public virtual string ToString();
    }