[C#基本程序结构Ⅲ]继承

继承

继承,能够定义可重用、扩展或修改父类行为的子类。 成员被继承的类称为基类。 继承基类成员的类称为派生类。

//基类
namespace ConsoleApp1
{
    class BaseClass
    {
        public int data1;
        public string data2;

        public void BaseClassFunction1()
        {
            Console.WriteLine("BaseClass:Function1");
        }
        public void BaseClassFunction2()
        {
            Console.WriteLine("BaseClass:Function2");
        }   
    }
}
//派生类1
namespace ConsoleApp1
{
    class DrivedClass1 : BaseClass
    {
    }
}
//派生类2
namespace ConsoleApp1
{
    class DrivedClass2 : BaseClass
    {
        public int data3;

        public void DrivedClass2Function1()
        {
            Console.WriteLine("DrivedClass2:Function");
        }
    }
}
//主程序
using ConsoleApp1;

namespace DEMO
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass bc = new BaseClass();
            bc.data1 = 34;
            bc.data2 = "abcde";
            Console.WriteLine(bc.data1);
            Console.WriteLine(bc.data2);
            bc.BaseClassFunction1();
            bc.BaseClassFunction2();

            //派生类可以使用基类的类成员
            DrivedClass1 dc1 = new DrivedClass1();
            dc1.data1 = 1;
            dc1.data2 = "12345";
            Console.WriteLine(dc1.data1);
            Console.WriteLine(dc1.data2);
            dc1.BaseClassFunction1();
            dc1.BaseClassFunction2();
            //派生类可以有自己新的类成员
            DrivedClass2 dc2 = new DrivedClass2();
            dc2.DrivedClass2Function1();
        }
    }
}

继承-this&base
①this可以访问当前类中定义的字段,属性和⽅法(有没有this都可以访问),有this可以让编译器给出提⽰,另外当⽅法的参数跟字段重名的时候,使⽤this可以表明访问的是类中的字段
②base可以调⽤⽗类中的公有⽅法和字段(有没有base都可以访问),但是加上base可以让编译器给出提⽰,把所有可以调⽤的字段和⽅法罗列出来⽅便选择

//基类
using System.Runtime.CompilerServices;

namespace ConsoleApp1
{
    class BaseClass
    {
        public int data1;
        public string data2;

        public void BaseClassFunction1()
        {
            Console.WriteLine("BaseClass:Function1");
        }
        public void BaseClassFunction2()
        {
            Console.WriteLine("BaseClass:Function2");
        }   
    }
}
//派生类1
namespace ConsoleApp1
{
    class DrivedClass1 : BaseClass
    {
    }
}
//派生类2
namespace ConsoleApp1
{
    class DrivedClass2 : BaseClass
    {
        public int data3;

        public void DrivedClass2Function1()
        {
            Console.WriteLine("DrivedClass2:Function");
        }

        public void DrivedClass2Function2()
        {
            this.BaseClassFunction1();
            this.BaseClassFunction2();
            this.DrivedClass2Function1();
            base.BaseClassFunction1();
            base.data1 = 2;
        }
    }
}
//主程序
using ConsoleApp1;

namespace DEMO
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass bc = new BaseClass();
            bc.data1 = 34;
            bc.data2 = "abcde";
            Console.WriteLine(bc.data1);
            Console.WriteLine(bc.data2);
            bc.BaseClassFunction1();
            bc.BaseClassFunction2();

            //派生类可以使用基类的类成员
            DrivedClass1 dc1 = new DrivedClass1();
            dc1.data1 = 1;
            dc1.data2 = "12345";
            Console.WriteLine(dc1.data1);
            Console.WriteLine(dc1.data2);
            dc1.BaseClassFunction1();
            dc1.BaseClassFunction2();
            //派生类可以有自己新的类成员
            DrivedClass2 dc2 = new DrivedClass2();
            dc2.DrivedClass2Function1();
            dc2.DrivedClass2Function2();
        }
    }
}
继承-virtual

①派生类可以通过提供重写实现代码来重写继承的成员,基类成员必须标记有 virtual 关键字,才能重写继承的成员
②在派⽣类中重写另外⼀个函数时,要使⽤override关键字显⽰声明
③在⼦类⾥⾯重写虚函数之后,不管在哪⾥调⽤都是调⽤重写之后的⽅法

//基类
using System.Runtime.CompilerServices;

namespace ConsoleApp1
{
    class MyBaseClass
    {
        public virtual string VirtualMethod()
        {
            return "Method is called in base class";
        }
    }
}
//派生类1
namespace ConsoleApp1
{
    class MyDerivedClass : MyBaseClass
    {
        public override string VirtualMethod()
        {
            return "Method is called in derivedclass.";
        }
    }
}

 继承-abstract&override

①使⽤abstract修饰的类为抽象类,抽象类只能是其他类的基类,不能与sealed、static⼀起使⽤
②abstract可以修饰抽象类中的⽅法或属性,该⽅法或属性不能包含实现,且访问级别不能为私有
③抽象类不能被实例化

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

namespace ConsoleApp1
{
    //抽象类
    public abstract class Class1
    {
        private int intData0;
        private int intData1;

        public void Function0()
        {
            Console.WriteLine("Function0");
        }
        //抽象类将不能声明主体
        public abstract void AbsClass();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    //抽象类的实现
    public class Class2 : Class1
    {
        public override void AbsClass()
        {
            Console.WriteLine("抽象类的实现");
        }
    }
}
namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
            //Class1 class1 = new Class1();     //cs0144
            Class2 class2 = new Class2();
            class2.Function0();
            class2.AbsClass();
            Console.ReadKey();
        }
    }
}

继承-sealed 

C#允许把类和⽅法声明为sealed

将类声明为密封类,则不能继承该类;

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

namespace ConsoleApp1
{
    //密封类
    public sealed class Class1
    {
        private int intData0;
        private int intData1;

        public void SeaClass()
        {
            Console.WriteLine("密封类的实现");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//将类声明为密封类,则不能继承该类
namespace ConsoleApp1
{
    //CS0509无法从密封类派生
    public class Class2 : Class1
    {
    }
}
namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
            Class1 class1 = new Class1();
            class1.SeaClass();
            Console.ReadKey();
        }
    }
}

将⽅法声明为密封方法,则不能重写该⽅法

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

namespace ConsoleApp1
{
    public class Class1
    {
        private int intData0;
        private int intData1;

        public virtual void SeaClass()
        {
            Console.WriteLine("密封类的实现");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class Class2 : Class1
    {
        public sealed override void SeaClass()
        {
            Console.WriteLine("派生类的实现");
        }
    }
    public class Class3 : Class2
    {
        public override void SeaClass()//CS0239 "Class3.SeaClass()": 继承成员"Class2.SeaClass()"是密封的,无法进行重写

        {
            Console.WriteLine("1");
        }
    }
}
namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
            Class1 class1 = new Class1();
            class1.SeaClass();
            Class2 class2 = new Class2();
            class2.SeaClass();
            Console.ReadKey();
        }
    }
}

 

posted @ 2022-12-23 16:29  SairenjiHaruna  阅读(30)  评论(0编辑  收藏  举报