广东外贸网站建设,如何制作网站连接数据库,wordpress term_id,大山子网站建设名人名言#xff1a;思想好比火星#xff1a;一颗火星会点燃另一颗火星。一个深思熟虑的教师和班主任#xff0c;总是力求在集体中创造一种共同热爱科学和渴求知识的气氛#xff0c;使智力兴趣成为一些线索#xff0c;以其真挚的、复杂的关系——即思想的相互关系把一个个…名人名言思想好比火星一颗火星会点燃另一颗火星。一个深思熟虑的教师和班主任总是力求在集体中创造一种共同热爱科学和渴求知识的气氛使智力兴趣成为一些线索以其真挚的、复杂的关系——即思想的相互关系把一个个的学生连接在一起。——苏霍姆林斯基
首先给出部分代码由此来分析一下运行过程中对象、字段的创建过程和编译过程中方法列表的创建过程。
public class Animal { public virtual void Eat() { Console.WriteLine(Animal Eat ); } public virtual void Sleep() { Console.WriteLine(Animal Sleep ); } public void Play() { Console.WriteLine(Animal Play ); } } public class Cat : Animal { public override void Eat() { base.Eat();//调用父类方法 Console.WriteLine(Cat Eat ); } public override void Sleep() { Console.WriteLine(Cat Sleep ); base .Sleep(); } } 以上代码 如果在Main方法中 通过 Animal a new Cat(); 来实现一个父类引用子类对象。 这句话首先是创建了一个Animal类型的a的引用然后 new Cat();创建了一个Cat的对象最后把这个a这个引用指向了 new Cat();这个对象的地址。在这个对象创建的过程中其实有很多步骤 首次访问(在此没有显示的写出类中的构造方法) 顺序子类的静态字段》子类静态构造》子类非静态字段》父类的静态字段》父类的静态构造》父类的非静态字段 》父类的构造函数》子类的构造函数 非首次访问顺序是一样的只不过少了中间静态字段和构造的过程 这个过程依次类推直到递归到Object结束在次过程中也是依次给父类分配内存的过程),且字段的在内存中的存储顺序是由上到下排列object类的字段 排在最前面 原因是如果父类和子类出现了同名字段则在子类对象创建时编译器会自动认为这是两个不同的字段而加以区别。 说了对象的创建其次是方法列表的创建 方法列表的创建是在编译时创建的而对象的创建是在运行时对象的创建是为了给方法列表一个引用的指针使其它们动态关联起来。 方法列表的创建顺序跟字段的的顺序是一样的也是先父类后子类。override 和 new 的不同 new主要是会阻断继承树和隐藏父类方法创建子类和父类同名的方法 父先子后的原因是在编译时创建方法列表的过程是先生成父类的方法列表而后在生成子类的方法列表的时候会把父类的方法复制一份 出来然后拿子类的方法去和父类的比较如果发现同名的方法则看子类的方法修饰符是override 还是 new如果是override 则覆盖父类 同名的方法以上所说的父类方法皆是virtual方法并且这里说的覆盖只是说覆盖方法的实现而并没有覆盖父类的方法列表通过base.父类方法名还是可以调用父类的方法 如果是new 则在内存中的不同位置创建一个同名的方法。 不同名的则直接创建。 完成之后我们可以通过 a这个引用来来调用Cat中的方法。 1.思考如果把上例中Animal的play方法移到Cat中在Main方法中打算通过a.Paly();来调用子类的Paly方法会发生什么现象 会编译不通过为什么呢 按理说子类就是用来扩展父类的理论上也允许子类有自己的特性啊方法、字段……。但问题不是出在子类而是出在了调用的位置不能通过a.Play();来调用这个方法可能大家又不解了会想 a就是通过 new Cat();这个对象啊出来的为什么不能调用自己的方法勒一层层的最终我们找到原因是在 Animal a 这个申明引用的位置。 在此要引入OO 的一个原则 关注对象原则——调用子类还是父类的方法取决于创建的对象是子类对象还是父类对象而不是它的引用类型而引用指针类型不同的区别决定了不同的对象在方法表中不同的访问权限。 由此结合子类可以调用父类方法和字段而父类不能调用子类方法和字段 这个概念。就可以知道原因了。 在说说OO中的另一个原则就近原则——对于同名字段或者方法编译器是按照其顺序查找来引用的也就是首先访问离它创建最近的字段或者方法。先贴一段代码然后通过代码来分析。 View Code class Program { static void Main(string [] args) { Animal a new Cat(); // MemberInfo[] m a.GetType().GetMembers(); // foreach (var item in m) // { // Console.WriteLine(item.Name); // } // a.Eat(); // a.Play(); //a.Sleep(); Console.WriteLine(a.AnimalName); } } public class Animal { public string AnimalName Animal ; } public class Cat : Animal { public string AnimalName Cat ; } 在代码的Main方法中 Animal a new Cat(); 这个A是Animal 类型的结合文章开始将的 在编译和运行过程中 子类、父类 的字段和方法以及实例化时候在内存中分配的先后位置可以得出Animal 类中的 AnimalName 在内存中的位置一定位于 Cat中AnimalName在内存中的位置的前面根据就近原则打印出的应该是Animal。 以上文章大致概括了在继承过程中的 在编译和运行过程中 子类、父类 的字段和方法以及实例化时候在内存中分配 和 执行的先后以及两个原则如有错误或者不足的地方请拍砖。后续后更深入的学习oo中的其它内容。