C#:abstract virual 区别 和 相同之处

来源:互联网 发布:淘宝助理怎么下载 编辑:程序博客网 时间:2024/06/05 19:10
1:
abstract 方法 必须 没有实现, 且必须被继承类(如果该类不是抽象类的话)实现.

声明了abstract方法的类必须为abstract类,abstract类可以有其他非抽象方法.

2:
virual方法必须有实现.别不必被继承类实现.
声明了virtual方法的类,不必是abstract类
3:
abstract方法只不过是virtual方法的纯粹版本,abstract方法也有virtual方法的动态机制(即运行时根据对象引用的具体类型调用相应的方法,也可以说当前引用中调用派生层次最深的方法).
4.

重写两种方法,必须在派生类中用override声明.如果不使用override的话

对于abstract方法:

编译器会报错,因为没有实现抽象类的方法.

对于virtual方法:

相当于覆盖了virtual方法,使用一个参数列表和返回值,函数名一样的方法. 该方法不再作为virtual方法,而是普通函数.虚函数搜索时将不再搜索该函数.

此时编译器会给出警告.因为你用一个函数原型几乎一模一样的方法覆盖了虚方法.如果确实需要这样做,在方法前加new关键字,显示表明要覆盖虚方法.

编译器不再给出警告.


综上.abstract方法,virual方法与C++中纯虚函数,虚函数的概念是一致的.

C++中
1.
纯虚函数必须没有实现
声明了纯虚函数的类一定是抽象基类(ABC)(自动成为,不必额外声明)
2.
而不是纯的虚函数,则必然有实现,否则就成了纯虚函数(除非进行方法声明,又不给出定义,并且没有 在声明后面指出这是纯虚函数,即 "= 0", 这种情况下,任何调用该方法的语句都会导致链接错误,相当于无用函数)
有虚函数的类,当然可以不必是抽象基类.
3.
纯虚函数和虚函数当然都有同样的动态机制.

所以,结论是:

C#中abstract方法,virual方法与C++中纯虚函数,虚函数的概念是一致的.


测试代码:

abstract public class animal
    {
        public abstract string get();
        public virtual string eat() { return "animal"; }
    }
    abstract public class waterAnimal : animal
    {
        //public override string get()
        //{
        //    return ToString();
        //}
        public override string eat() { return "wateranimal"; }
    }
    public class fish : waterAnimal
    {
        public override string get()
        {
            return ToString();
        }
        new public string eat() { return "fish"; }
    }


    public class landAnimal:animal
    {
        public override string get()
        {
            return this.ToString();
        }
        public string get(int a)
        {
            return "notOverride";
        }
    }


    public class cat:landAnimal
    {
        public override string  get()
        {
          return this.ToString();
        }
    }
    public class dog : landAnimal
    {
        public override string get()
        {
            return this.ToString();
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            animal a = new fish();
            Console.WriteLine(a.eat());
            //waterAnimal w = new waterAnimal();
            //Console.WriteLine(w.eat());

            a = new cat();
            landAnimal l = new cat();
            Console.WriteLine(a.get());
            Console.WriteLine(l.get());

            a = new dog();

            try
            {
                cat c = a as cat;
                c = (cat)a;
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
            
        }
    }



哪里说错,请纠正.
原创粉丝点击