• c#基础之继承(一)


    1.1派生

     继承是为了扩展现有类型来添加更多功能来设计的。


    派生类继承了除了构造器和析构器(析构主要是用来释放运行时暂用的内存的,在C#中一般很少用,一般用垃圾回收器自动释放的!)之外的所有基类成员

    1.1.2private访问修饰符 

    派生类不能访问基类的私有成员,

    1.1.3protected访问修饰符

     基类中的受保护的 成员只能从基类以及其派生链中的其他类中访问。

    比如;


    public class Program
    {
    static void Main(string[] args)
    {
    B T = new B();
    T.id//这时候报错,Program没有继承A,所以报错。
    }
    }
    public class A
    {
    protected int id { get; set; }
    }
    public class B : A
    {
    public void save()
    {
    int test = id;
    }
    }

    1.2virtual修饰符

    (https://www.cnblogs.com/green-jcx/p/9023141.html  具体的属性和字段的区别的可以参考这个文章)

    c#支持重写实例方法和属性,但是不支持重写字段或者任何静态成员。为了进行重写,要求在基类和派生类中都显示执行一个操作。在基类中,必须将允许重写的每个成员标记成virtual(java中默认的都是虚方法,但是c#中磨人的是非虚方法)。假如一个public和protected成员没有包含virtual修饰符,就不允许重写。c#不允许隐式重写,java可以。

    eg:

       public  class Program
        {
           public virtual string Name { get; set; }
        }
    
       public class Test : Program
       {
           public string FirstName { get; set; }
           public string LastName { get; set; }
    
           public override string Name
           { 
               get
               {
                   return LastName + LastName;
               }
               set
               {
                   string[] v = value.Split(',');
                   LastName = v[0];  
                   FirstName = v[1];
               }
           }
       
       
       }

    如上述代码:“运行时”遇到虚方法的时候,他会调用虚成员派生的最远的,重写的实现。所以在调用Program类中的 Name属性的时候执行的是重写的代码。所以虚方法不应该包含关键代码,否则会导致原始代码永远得不到调用。只有实例成员(包括实例数据和实例方法 ,必须通过对象来调用,不能使用类名调用。)才可以是virtual的。   

    1.3new修饰符

    eg:

     public class Program
        {
            public void Display()
            {
                Console.WriteLine("Program");
    
            }
    
            public static void Main()
            {
                Test2 t2 = new Test2();
                Program p = t2;
                Test t = t2;
                Test1 t1 = t2;
    
                t2.Display(); 
                p.Display();
                t.Display();
                t1.Display();
    
                Console.ReadLine();
               // Console.WriteLine("t");
    
    
            }
    
    
        }
    
       public class Test : Program
       {
           //可以被重写
           public virtual void Display()
           {
               Console.WriteLine("Test");
    
           }
        
       }
       public class Test1 : Test
       {
           public override void Display()
           {
               Console.WriteLine("Test1"); 
           }  
       }
       public class Test2 : Test1
       {
           public new  void Display()
           {
               Console.WriteLine("Test2");
           }
       }

    上述代码的结果为下:

    Test2
    Program
    Test1
    Test1

    因为调用重写的方法的时候,找的是派生的最远的方法,但是使用new修饰符之后正好相反,它隐藏了派生类,找的是基类中的方法,Test2的基类是Test1,所以输出是Test1。

     1.4sealed修饰符 
    一般很少将整个类都密封,可以密封单独虚成员,也可以密封整个类,但是需要注意的是被密封的类或者虚成员必须是继承类,不能是基类,
      public   class Program
        {
            public  virtual    void Display()
            {
                Console.WriteLine("Program"); 
            } 
          
        }
    
       public   class Test : Program
       {
           //这个方法不会被继承Test类的派生类重写了
           public override sealed void Display()
           {
               Console.WriteLine("Test");
    
           }
        
       }

    1.5base关键字

     public   class Program
        {
            public Program()
            {
                Console.WriteLine("Program构造函数"); 
            }
            public  virtual    void Display()
            {
                Console.WriteLine("Program"); 
            } 
            public static void Main()
              {
            //    Test2 t2 = new Test2();
            //    Program p = t2;
                  Test t = new Test();
                  t.Display();
                   
            //    Test1 t1 = t2;
    
            //    t2.Display(); 
            //    p.Display();
            //    t.Display();
            //    t1.Display();
    
            Console.ReadLine();
               // Console.WriteLine("t"); 
    
            } 
        }
    
       public    class Test : Program
       {
           public Test():base()
           {
               Console.WriteLine("Test构造函数"); 
           }
           //可以被重写
           public override   void Display()
           {
               Console.WriteLine("Test");
    
           }
        

    结果是:

    Program构造函数
    Test构造函数
    Test

    所以使用base()继承基类的构造方法,会同时执行派生类和基类的构造方法。

    下面代码是继承

    public class Program
    {
    public void N()
    {
    Console.WriteLine("N");
    }
    public virtual void Display()
    {
    Console.WriteLine("Program");
    }
    public static void Main()
    {
    // Test2 t2 = new Test2();
    // Program p = t2;
    Test t = new Test();
    t.Display();

    // Test1 t1 = t2;

    // t2.Display();
    // p.Display();
    // t.Display();
    // t1.Display();

    Console.ReadLine();
    // Console.WriteLine("t");

    }
    }

    public class Test : Program
    {

    //可以被重写
    public override void Display()
    {
    base.N();
    base.Display();
    Console.WriteLine("Test");

    }

    }

    结果:

    N
    Program
    Test

    base 关键字用于从派生类中访问基类的成员:
    调用基类上已被其他方法重写的方法。
    指定创建派生类实例时应调用的基类构造函数。
    基类访问只能在构造函数、实例方法或实例属性访问器中进行。

  • 相关阅读:
    tyvj1117 拯救ice-cream
    codevs3410 别墅房间
    codevs1099 字串变换
    codevs1226 倒水问题
    codevs2449 骑士精神
    codevs1225 八数码难题
    Wikioi 3776 生活大爆炸版石头剪子布
    codevs1197 Vigenère密码
    枚举 + exgcd
    C++ 排序引用的优化
  • 原文地址:https://www.cnblogs.com/anjingdian/p/12093896.html
Copyright © 2020-2023  润新知