• 继承和多态


    继承、封装、多态是面向对象的三大特性。这里主要理解一下继承和多态。继承可以理解为子类继承父类。

    其中有几个词在继承和多态中经常用到:new、virtual、override、sealed、abstract

    结合例子看一下这几个词的用法和说明:

    1、new:我认为就是一个标记。目的就是为了避免冲突。父类中的方法和子类中的方法一模一样,子类的方法前加:new,来避免冲突。

    代码:

     public class Parent
        {
            public Parent()
            {
                Console.WriteLine("父类构造");           
            }
            public void GaGa()
            {
                Console.WriteLine("父类的【GaGa】叫方法");
            }
            public virtual void Walk()
            {
                Console.WriteLine("父类走的动作");
            }
        }
        public class Children : Parent
        {
            public Children()
            {
                Console.WriteLine("子类的构造");            
            }
             new public void GaGa()
            {
                Console.WriteLine("子类方法GaGa与父类未公开继承的GaGa方法重叠,子类用new将父类方法隐藏。");
            }
            public override void Walk()
            {
                Console.WriteLine("子类走的动作");
            }
        }   
    View Code

    父类Parent中: 

    public void GaGa()
    {
          Console.WriteLine("父类的【GaGa】叫方法");
    }


    子类中同样有这样的方法:加入new方法

     new public void GaGa()
    {
          Console.WriteLine("子类方法GaGa与父类未公开继承的GaGa方法重叠,子类用new将父类方法隐藏。");
    }

    那我们调用时这样写:

     class Program
        {
            static void Main(string[] args)
            {
                Parent p = new Children();
                //父类GaGa()方法
                p.GaGa();           
                Console.WriteLine("---------------------------------------");       
              
            }
        }

    因为有new的区分父类和子类的方法(完全相同的方法),所以调用的是父类的GaGa方法。

    执行结果截图:

    分析执行结果:子类继承父类,实例化子类时,先构造父类构造,再构造子类构造,之后我们调用了子类中与父类相同方法的GaGa(),但是我们用new在子类方法前加以区分。

    二、virtual  虚方法,也是一个标记,标记这个类中的方法可以在子类中重写覆盖(override)或者隐藏(new)

    1、override

     public class Parent
        {
            public Parent()
            {
                Console.WriteLine("父类构造");           
            }
            public void GaGa()
            {
                Console.WriteLine("父类的【GaGa】叫方法");
            }
            public virtual void Walk()
            {
                Console.WriteLine("父类走的动作");
            }       
        }
        public class Children : Parent
        {
            public Children()
            {
                Console.WriteLine("子类的构造");            
            }
             new public void GaGa()
            {
                Console.WriteLine("子类方法GaGa与父类未公开继承的GaGa方法重叠,子类用new将父类方法隐藏。");
            }
            public override void Walk()
            {
                Console.WriteLine("子类走的动作,完全覆盖父类公开可以继承的此方法");
            }       
        }   

    这里除了注意父类和子类的walk()方法的写法,还需注意:

      Parent p = new Children();
                //父类GaGa()方法
                p.GaGa();    ----------这个是子类用new方法加以区别父类的方法
                p.Walk();    ----------这个是子类用 override 重写覆盖父类方法

    注意运行结果:

    我们实例化的是子类,但是赋给了父类引用,而子类中正好Walk()方法覆盖了父类方法。这样调用的时候就是子类的Walk()

    方法的实现。

    (2)new

    public class Parent
        {
            public Parent()
            {
                Console.WriteLine("父类构造");           
            }
            public void GaGa()
            {
                Console.WriteLine("父类的【GaGa】叫方法");
            }
            public virtual void Walk()
            {
                Console.WriteLine("父类走的动作");
            }       
        }
        public class Children : Parent
        {
            public Children()
            {
                Console.WriteLine("子类的构造");            
            }
             new public void GaGa()
            {
                Console.WriteLine("子类方法GaGa与父类未公开继承的GaGa方法重叠,子类用new将父类方法隐藏。");
            }
            new public  void Walk()-------------------------看这!!!!!!!!!
            {
                Console.WriteLine("子类走的动作,完全覆盖父类公开可以继承的此方法");
            }
           
        }   

    区别于上面,父类Walk()标记为virtual 可以重写,现在的子类是用new也是区别于相同方法

    调用结果:

    对的,子类没有用override覆盖父类方法,所以调用的还是父类的那个自己的Walk()方法。

    三、override:上面已经提到是在父类中用到virtual,子类就用override进行重写。

    四、sealed密封的,密封类是不可以继承的。

    五、abstract:抽象,抽象类中的抽象方法,继承了此类的子类必须重写抽象实现

    总结:

    关键字 可以拥有此关键字的对象 作用    
    new 子类与父类拥有相同方法的子类方法 隐藏父类相同方法,这样子类和父类的方法相互独立,不会存在冲突    
    virtual 父类的方法 父类的此方法可以让父类进行重写,子类可以根据实际情况决定是否重写。    
    override 子类对应重写父类的方法,用此标记。 用于子类对父类标记virtual的方法的重写标记,这样就实实在在的覆盖了父类的那个可以允许子类重写的方法。记住是覆盖。    
    abstract 用于类和方法 类--不可以实例化,方法--如果继承此类,就必须实现abstract方法。    
    sealed 表示,该类不可以继承    
  • 相关阅读:
    这两年
    Ubuntu 14.04 更新 setuptools 至 19.2 版本
    leetcode 编译问题:Line x: member access within null pointer of type 'struct TreeNode'
    C++ 将 std::string 转换为 char*
    LeetCode in action
    Ubuntu下 fatal error: Python.h: No such file or directory 解决方法
    Mac OS X 清除DNS缓存
    Mac OS X 避免产生临时文件 .DS_Store
    Mac OS X 显示和隐藏文件
    解决 ln -s 软链接产生的Too many levels of symbolic links错误
  • 原文地址:https://www.cnblogs.com/sunchong/p/3495142.html
Copyright © 2020-2023  润新知