zoukankan      html  css  js  c++  java
  • C#基础知识——类的继承

      继承是C#的三大特性之一,它实现了多态性和代码复用

      我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类。

      Student、Teacher、Driver    子类 派生类
      Person                  父类 基类

    1.  子类继承了父类,那么子类从父类那里继承过来了什么?
      首先,子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段。

      子类对象可以调用父类中的成员,但是父类对象永远都只能调用自己的成员。

    2.  问题:子类有没有继承父类的构造函数?

      答:子类并没有继承父类的构造函数,但是。子类会默认的调用父类无参数的构造函数,创建父类对象,让子类可以使用父类中的成员。所以,如果在父类中重新写了一个有参数的构造函数之后,那个无参数的就被干掉了,子类就调用不到了,所以子类会报错。

      解决办法:
      1)、在父类中重新写一个无参数的构造函数。
      2)、在子类中显示的调用父类的构造函数,使用关键字:base()

    3.  在创建子类对象的时候,为什么会先在子类对象的内部创建一个父类对象出来?

      由于继承的原因,子类能够使用父类的属性和方法,如果没有创建父类的对象的话,就不能够使用父类的属性和方法了。

    4. 继承的特性

      1、继承的单根性:一个子类只能有一个父类,不允许多重继承。
      2、继承的传递性: 祖宗的东西迟早都是我的,子类的派生类也可以调用子类的父类的方法。

        A 继承 B,C是A的派生类,那么C也可以调用B的属性和方法。

    5. object类是所有类的基类

    6. new关键字的作用

       1)、创建对象      Class1 c = new Class1();
         2)、隐藏从父类那里继承过来的同名成员。
          隐藏的后果就是子类调用不到父类的成员。
          子类与父类 尽量不要出现同名的成员,如果有请使用new来隐藏

        public class Animal 
        {
            public virtual void Eat() { Console.WriteLine("Animal eat");     }
        }
        public class Cat: Animal 
        {
            public new void Eat() { Console.WriteLine("Cat eat"); }
            public void Eating() { Console.WriteLine("Cat eating"); }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Animal a = new Animal();
                a.Eat();
    
                Animal ac = new Cat();
                ac.Eat(); //输出:Animal eat 并非Cat eat
               //ac 这个对象无法调用 Cat类的eating方法 
    
                Cat c = new Cat();
                c.Eat();
            }
        }                 

    输出结果:

      Animal eat

      Animal eat

      Cat eat

    第2句为什么会是 Animal eat 而非Cat eat呢?

       因为,使用new关键字后,使得Cat中的Eat()方法和Animal中的Eat()方法成为毫不相关的两个方法,只是它们的名字碰巧相同而已。

       此时,对于ac这个对象而言,Cat中的Eat()方法就如同Eating()方法了,它们都是Cat类独有的方法,ac无法调用到它们。

      假如我们只使用了new关键字,如果Cat类没用从Animal类继承Eat()方法,编译器会输出警告!

        在程序中,Animal类型的对象ac指向了Cat类型的对象所占据的内存时,Cat中的Eat()方法和Animal中的Eat()方法毫无关系,所以Cat中的Eat()方法就是Cat类中独有的方法了。这样ac无法调用Cat中的Eat方法,于是就会去调用Animal中的Eat方法。

     

    7. 里氏转换原则  

      1)、子类可以赋值给父类

       2)、如果父类中装的是子类对象,那么可以讲这个父类强转为子类对象。

                Hero[] heros = new Hero[10];
                Random ran = new Random();
                // 里氏转换的第一条规则: 子类可以赋值给父类
                for (int i = 0; i < heros.Length; i++)
                {
                    int random = ran.Next(1,6);
                    switch (random) 
                    {
                        case 1 :
                            heros[i] = new ZhuGeLiang();
                            break;
                        case 2:
                            heros[i] = new SunShangXiang();
                            break;
                        case 3:
                            heros[i] = new SiMaYi();
                            break;
                        case 4:
                            heros[i] = new CaiWenJi();
                            break;
                        case 5:
                            heros[i] = new Hero();
                            break;
                    }
                }
    
                //里氏转换的第2条规则:如果父类中装的是子类的对象,那么就可以将这个父类强转为子类的对象。
                for (int i = 0; i < heros.Length; i++)
                {
                    //heros[i].LaunchSkill();
                    if (heros[i] is ZhuGeLiang)
                    {
                        ((ZhuGeLiang)heros[i]).WatchStar();
                    }
                    else if (heros[i] is SunShangXiang)
                    {
                        ((SunShangXiang)heros[i]).GetMarried();
                    }
                    else if (heros[i] is SiMaYi)
                    {
                        ((SiMaYi)heros[i]).GostSkill();
                    }
                    else if (heros[i] is CaiWenJi)
                    {
                        ((CaiWenJi)heros[i]).SorrowSong();
                    }
                    else
                    {
                        heros[i].LaunchSkill();
                    }
    
                }
    
                Console.ReadKey();
            }
    
            class Hero 
            {
                public void LaunchSkill() 
                {
                    Console.WriteLine("我是白板,没有技能。");
                }
            }
    
            class ZhuGeLiang : Hero 
            {
                public void WatchStar() 
                {
                    Console.WriteLine("知天易逆天难。");
                }
            }
    
            class SunShangXiang : Hero 
            {
                public void GetMarried() 
                {
                    Console.WriteLine("他好,我也好。");
                }
            }
    
            class SiMaYi : Hero 
            {
                public void GostSkill() 
                {
                    Console.WriteLine("吾乃天命之子。");
                }
            }
    
            class CaiWenJi : Hero
            {
                public void SorrowSong() 
                {
                    Console.WriteLine("悲歌可当泣,远望可当归。");
                }
            }
  • 相关阅读:
    URLEncode解决url中有特殊字符的问题
    监控系统概览
    SpringBoot 上传文件夹
    关于postgresql报 ERROR: XXX does not exist
    postgresql学习
    git学习
    学习博客
    面试准备
    jvm
    线程池面试题
  • 原文地址:https://www.cnblogs.com/lcxBlog/p/4493037.html
Copyright © 2011-2022 走看看