二、C#图解教程第七章--类和继承

一、类继承
 
示例:
 

 

 

 

 

 

 

 

 

注意:
1.所有的类都派生自object类
2.C#支支持单继承
3.继承的层次没有限制
 

 

 

 
屏蔽基类成员
派生类不能删除基类成员,但可以声明和基类相同的成员来屏蔽基类成员
 

 

 

class SomeClass
    {
        public string Field1 = "SomeClass--Field1";
        public void Mehod1(string value)
        {
            Console.WriteLine("SomeClass Method1:{0} ",value);
        }
    }
    
    1.不加new关键字
    class OtherClass:SomeClass
    {
      public string Field1 = "OtherClass--Field1";
      public void Mehod1(string value)
        {
            Console.WriteLine("OtherClass Method1:{0} ", value);
        }
    }
    2.关键字new放在访问修饰符后
    class OtherClass:SomeClass
    {
        public new string Field1 = "OtherClass--Field1";
        public new void Mehod1(string value)
        {
            Console.WriteLine("OtherClass Method1:{0} ", value);
        }
    }
    3.关键字new放在访问修饰符前
     class OtherClass:SomeClass
    {
        new public string Field1 = "OtherClass--Field1";
        new public void Mehod1(string value)
        {
            Console.WriteLine("OtherClass Method1:{0} ", value);
        }
    }
 
static void Main(string[] args)
   {
    OtherClass otherclass = new OtherClass();
    otherclass.Mehod1(otherclass.Field1);
    Console.ReadLine();
    }

  

 

 

 

 
基类访问
如果派生类想访问被隐藏的继承成员,可以使用基类访问表达式
class OtherClass:SomeClass
    {
        new public string Field1 = "OtherClass--Field1";
        new public void Mehod1(string value)
        {
            Console.WriteLine("OtherClass Method1:{0} ", value);
            访问被隐藏的继承成员
            Console.WriteLine("SomeClass Method1:{0} ", base.Field1);
        }
    }
 
 
使用基类的引用
派生类的实例:基类的实例加上派生类新增的成员。
派生类的引用:指向整个类,包括基类部分的引用。
基类的引用:可以通过强制转换将派生类的引用转为基类的引用。
示例:
static void Main(string[] args)
        {
            DeriverClass deriverclass = new DeriverClass();
            deriverclass.Printf();
            BaseClass baseclass=(BaseClass)deriverclass;
            baseclass.Printf();
            Console.ReadLine();
        }
class BaseClass
    {
        public void Printf()
        {
            Console.WriteLine("This is BaseClass!");
        }
    }
    class DeriverClass:BaseClass
    {
        new  public void Printf()
        {
            Console.WriteLine("This is DeriverClass!");
        }
    }
 
 

 

 

 

 

 

虚方法和复写方法
解决的问题:基类的引用不能访问派生类的对象
示例:
class BaseClass
    {
        public void Printf()
        {
            Console.WriteLine("This is BaseClass!");
        }
    }
    class DeriverClass:BaseClass
    {
        new  public void Printf()
        {
            Console.WriteLine("This is DeriverClass!");
        }
    }
 
static void Main(string[] args)
        {
            DeriverClass deriverclass = new DeriverClass();
            BaseClass baseclass=(BaseClass)deriverclass;
            baseclass.Printf();
            Console.ReadLine();
        }

 

 

 

 

 
虚方法可以使基类的引用访问派生类的对象

 

 

修改以上代码(使用虚方法):
class BaseClass
    {
        public virtual void Printf()
        {
            Console.WriteLine("This is BaseClass!");
        }
    }
    class DeriverClass:BaseClass
    {
         public override void Printf()
        {
            Console.WriteLine("This is DeriverClass!");
        }
    }
 
static void Main(string[] args)
        {
            DeriverClass deriverclass = new DeriverClass();
            BaseClass baseclass=(BaseClass)deriverclass;
            baseclass.Printf();
            Console.ReadLine();
        }

 

 
 

 

 

 

 

构造函数的执行
 

 

 

构造函数的初始化语句
(1)使用base调用基类的构造函数
public class A
    {
        public A(string s1,string s2)
        {
            Console.WriteLine("Base class A"+"  "+s1+"  "+s2);
        }
    }

    public class B:A
    {
        string str1;
        string str2;
        public B():base("aaa","bbb")
        {
            Console.WriteLine("Class B"+"  "+str1+"  "+str2);
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            B b = new B();
            Console.ReadLine();
        }
    }

 

 

 

 

(2)使用this调用当前类的构造函数
public class A
    {
        public A()
        {
            Console.WriteLine("Base class A");
        }
    }

    public class B:A
    {
        string str1;
        string str2;
        public B():this("aaa","bbb")
        {
            Console.WriteLine("Class B"+"  "+str1+"  "+str2);
        }

        public B(string s1, string s2) : base()
        {
            str1 = s1;
            str2 = s2;
        }
 
class Program
    {
        static void Main(string[] args)
        {
            B b = new B();
            Console.ReadLine();
        }
    }

 

 

 

类访问修饰符
 
 

 

 

程序集间的继承
不同程序集之间的继承时,基类需要在一个程序集中生成dll文件,在另一个程序集中引用这个dll文件,并应用dll文件中的命名空间,方可继承另一个程序集中的类。
 
 

 

 

 

 

 

 

成员访问修饰符
 
静态类

 

 

静态类用于存放不受实例影响的数据和函数
(1)静态类必须用static标记
(2)静态类的所有成员必须都是静态的
(3)静态类不能被继承
(4)静态类只有一个静态构造函数
静态类扩展:
(1)静态类可以有静态构造函数,静态构造函数不可以被继承
(2)静态构造函数不可被直接调用,当创建类实例或引用任何静态成员之前,静态构造函数被自动执行,并且
   只执行一次。
(3)静态类在内存中是一直有位置的;非静态类在实例化后是在内存中是独立的,它的变量不会重复,在使用后会及时销毁,所以不会出现未知的错误。在C#中静态成员是比较敏感的东西,在不是十分确认的情况下不要使用;
 
C#的常量
readonly为运行时常量,程序运行时进行赋值,赋值完成后便无法更改,因此也有人称其为只读变量。
const为编译时常量,程序编译时将对常量值进行解析,并将所有常量引用替换为相应值。
 
a.声明及初始化
readonly常量只能声明为类字段,支持实例类型或静态类型,可以在声明的同时初始化或者在构造函数中进行初始化,初始化完成后便无法更改。
const常量除了可以声明为类字段之外,还可以声明为方法中的局部常量,默认为静态类型(无需用static修饰,否则将导致编译错误),但必须在声明的同时完成初始化。
b.数据类型支持
由于const常量在编译时将被替换为字面量,使得其取值类型受到了一定限制。const常量只能被赋予数字(整数、浮点数)、字符串以及枚举类型
c.性能比较
const直接以字面量形式参与运算,性能要略高于readonly,但对于一般应用而言,这种性能上的差别可以说是微乎其微。
d.适用场景
在下面两种情况下:
a.取值永久不变(比如圆周率、一天包含的小时数、地球的半径等)
b.对程序性能要求非常苛刻
可以使用const常量,除此之外的其他情况都应该优先采用readonly常量。
 
 
 
扩展方法
扩展方法用于在不修改一个类的代码情况下,为一个类增加一个方法。具体的实现有两种方式,一种是通过创建一个新的示例去调用扩展的方法,另一种是不创建实例,在原来类的基础上调用扩展的方法。

 

 

扩展方法的结构:
 
 

 

 

 

 

 

posted @ 2020-07-05 10:24  我瘦够了  阅读(145)  评论(0编辑  收藏  举报