大家好,小弟正在学习C#,现在学的是蒙蒙呼呼的,觉得:虚函数(Virtual),抽象函数(abstract)和接口他们不都是只提供函数名称,然后再类中去实现代码吗?为什么要有这么多呢?
请大家帮忙分析它们之间的不同,最好有个例子,或者是能说明白,这三个东西分别在什么时候用。

解决方案 »

  1.   

    sf自己坐,我在C#怎么也有五个星?没在这儿回答过问题啊。
    唉!惭愧啊!
      

  2.   

    1.虚函数(Virtual),可以写方法的实现,不一定要被继承。抽象函数(abstract)不能写方法的实现,必须被继承
      

  3.   

    虛函數:由virtual聲明,它允許在派生類中被重寫,要重寫方法,必須先聲名為virtual
    public class myclass
    {
    public virtual int myint()
    {
    函數体;
    }
    }
    class myclass1:myclass
    {
    public override int myint()
    {
    函數体1;
    }
    }抽象類、抽象函數:由abstract聲明,在抽象類中可以定義抽象方法,抽象方法基本沒有執行代碼,派生類必須重寫它,提供其執行代碼
    public abstract class myclass
    {
    public abstract int myint();
    }
    public class myclass1:myclass
    {
    public override int myint()
    {
    函數体;
    }
    }接口類:由interface聲明,是特殊的抽象類,是方法、屬性、事件和索引符的組合,沒有字段,其成員無執行方式,無構造函數,不允許進行運算符重載,接口和它的成員沒有任何訪問修飾符,它總是公共的,不能聲明為虛擬或靜態,繼承自接口的派生類必須實現接口中的所有方法
    interface Imyinterface
    {
    void myfunction();
    string name
    {
    get;
    set;
    }
    }
    class myclass:Imyinterface
    {
    void myfunction()
    {
    函數体;
    }
    string name
    {
    get
    {
    return name;
    }
    set
    {
    name=value;
    }
    }
    }
      

  4.   

    http://www.0531s.com/www/9/2008-01/76841.html
    看看有沒有能幫到你的
      

  5.   

    1.virtual:允许被重写,但不强制要求。声明时提供其自身实现;
    2.abstract:强制要求其继承者重写。声明时不提供其自身的实现,抽象类不能被实例化;
    3.interface:接口就是协议,其声明的成员(属性,方法,事件和索引器)必须由其继承的类实现。接口不能直接被实例化。虚方法与抽象方法的区别在于,虚方法提供自身的实现,并且强制要求子类重写;而抽象方法不提供自身的实现,并且强制子类重写。抽象类与接口很相似,但是思路不一样。接口是公开类的成员,而抽象类则是抽象类成员以要求子类继承并实现。
      

  6.   

    virtual   关键字用于修改方法或属性的声明,在这种情况下,方法或属性被称作虚拟成员。虚拟成员的实现可由派生类中的重写成员更改。   
      ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/csref/html/vclrfVirtualPG.htm   
        
      abstract   修饰符用于表示所修饰的类是不完整的,并且它只能用作基类。   
      ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/csspec/html/vclrfcsharpspec_10_1_1_1.htm   
        
      interface   
      一个接口定义一个协定。实现接口的类或结构必须遵守其协定。   
      ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/csref/html/vcrefTheInterfaceType.htm   
      ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconInterfaces.htm   
        
      抽象类和接口   
      ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/csspec/html/vclrfcsharpspec_13_4_5.htm
      

  7.   

    virtual(C# 参考) virtual 关键字用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象。例如,此方法可被任何继承它的类重写。
    public virtual double Area() 
    {
        return x * y;
    }
    虚拟成员的实现可由派生类中的重写成员更改。有关使用 virtual 关键字的更多信息,请参见使用 Override 和 New 关键字控制版本(C# 编程指南)和了解何时使用 Override 和 New 关键字(C# 编程指南)。
    调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。默认情况下,方法是非虚拟的。不能重写非虚方法。virtual 修饰符不能与 static、abstract 和 override 修饰符一起使用。除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。在静态属性上使用 virtual 修饰符是错误的。通过包括使用 override 修饰符的属性声明,可在派生类中重写虚拟继承属性。在该示例中,Dimensions 类包含 x 和 y 两个坐标和 Area() 虚方法。不同的形状类,如 Circle、Cylinder 和 Sphere 继承 Dimensions 类,并为每个图形计算表面积。每个派生类都有各自的 Area() 重写实现。根据与此方法关联的对象,通过调用正确的 Area() 实现,该程序为每个图形计算并显示正确的面积。在前面的示例中,注意继承的类 Circle、Sphere 和 Cylinder 都使用了初始化基类的构造函数,例如: public Cylinder(double r, double h): base(r, h) {}// cs_virtual_keyword.cs
    using System;
    class TestClass
    {
        public class Dimensions
        {
            public const double PI = Math.PI;
            protected double x, y;
            public Dimensions()
            {
            }
            public Dimensions(double x, double y)
            {
                this.x = x;
                this.y = y;
            }        public virtual double Area()
            {
                return x * y;
            }
        }    public class Circle : Dimensions
        {
            public Circle(double r) : base(r, 0)
            {
            }        public override double Area()
            {
                return PI * x * x;
            }
        }    class Sphere : Dimensions
        {
            public Sphere(double r) : base(r, 0)
            {
            }        public override double Area()
            {
                return 4 * PI * x * x;
            }
        }    class Cylinder : Dimensions
        {
            public Cylinder(double r, double h) : base(r, h)
            {
            }        public override double Area()
            {
                return 2 * PI * x * x + 2 * PI * x * y;
            }
        }    static void Main()
        {
            double r = 3.0, h = 5.0;
            Dimensions c = new Circle(r);
            Dimensions s = new Sphere(r);
            Dimensions l = new Cylinder(r, h);
            // Display results:
            Console.WriteLine("Area of Circle   = {0:F2}", c.Area());
            Console.WriteLine("Area of Sphere   = {0:F2}", s.Area());
            Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
        }
    }
    输出
      
    Area of Circle   = 28.27
    Area of Sphere   = 113.10
    Area of Cylinder = 150.80
     
      

  8.   

    abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。在此例中,类 Square 必须提供 Area 的实现,因为它派生自 ShapesClass:
            abstract class ShapesClass
    {
        abstract public int Area();
    }
    class Square : ShapesClass
    {
        int x, y;
        // Not providing an Area method results
        // in a compile-time error.
        public override int Area()
        {
            return x * y;
        }
    }
    有关抽象类的更多信息,请参见抽象类、密封类及类成员(C# 编程指南)。抽象类具有以下特性:抽象类不能实例化。抽象类可以包含抽象方法和抽象访问器。不能用 sealed(C# 参考)修饰符修改抽象类,这意味着抽象类不能被继承。从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。在方法或属性声明中使用 abstract 修饰符以指示方法或属性不包含实现。抽象方法具有以下特性:抽象方法是隐式的虚方法。只允许在抽象类中使用抽象方法声明。因为抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。例如: 
    public abstract void MyMethod();
    实现由一个重写方法提供,此重写方法是非抽象类的成员。在抽象方法声明中使用 static 或 virtual 修饰符是错误的。 除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。在静态属性上使用 abstract 修饰符是错误的。在派生类中,通过包括使用 override 修饰符的属性声明,可以重写抽象的继承属性。 抽象类必须为所有接口成员提供实现。 实现接口的抽象类可以将接口方法映射到抽象方法上。例如:
    interface I 
    {
        void M();
    }
    abstract class C: I 
    {
        public abstract void M();
    }
    在本例中,DerivedClass 类是从抽象类 BaseClass 派生的。抽象类包含一个抽象方法 AbstractMethod 和两个抽象属性 X 和 Y。// abstract_keyword.cs
    // Abstract Classes
    using System;
    abstract class BaseClass   // Abstract class
    {
        protected int _x = 100;
        protected int _y = 150;
        public abstract void AbstractMethod();   // Abstract method
        public abstract int X    { get; }
        public abstract int Y    { get; }
    }class DerivedClass : BaseClass
    {
        public override void AbstractMethod()
        {
            _x++;
            _y++;
        }    public override int X   // overriding property
        {
            get
            {
                return _x + 10;
            }
        }    public override int Y   // overriding property
        {
            get
            {
                return _y + 10;
            }
        }    static void Main()
        {
            DerivedClass o = new DerivedClass();
            o.AbstractMethod();
            Console.WriteLine("x = {0}, y = {1}", o.X, o.Y);
        }
    }
    输出
    x = 111, y = 161在上面的示例中,如果试图通过使用下面的语句将抽象类实例化:
    BaseClass bc = new BaseClass();   // Error
    将出现错误,指出编译器无法创建抽象类“BaseClass”的实例。
      

  9.   

    看看这个帖子:http://topic.csdn.net/u/20080220/16/fedb74cd-95e1-4ab5-a2bb-934c3e9f017c.html
      

  10.   

    接口只包含方法、委托或事件的签名。方法的实现是在实现接口的类中完成的,如下面的示例所示:
            interface ISampleInterface
    {
        void SampleMethod();
    }class ImplementationClass : ISampleInterface
    {
        // Explicit interface member implementation: 
        void ISampleInterface.SampleMethod()
        {
            // Method implementation.
        }    static void Main()
        {
            // Declare an interface instance.
            ISampleInterface obj = new ImplementationClass();        // Call the member.
            obj.SampleMethod();
        }
    }
    接口可以是命名空间或类的成员,并且可以包含下列成员的签名: 方法 属性 索引器 事件 一个接口可从一个或多个基接口继承。当基类型列表包含基类和接口时,基类必须是列表中的第一项。实现接口的类可以显式实现该接口的成员。显式实现的成员不能通过类实例访问,而只能通过接口实例访问,例如:有关显式接口实现的更多详细信息和代码示例,请参见显式接口实现(C# 编程指南)。
    下面的示例演示了接口实现。在此例中,接口 IPoint 包含属性声明,后者负责设置和获取字段的值。Point 类包含属性实现。// keyword_interface_2.cs
    // Interface implementation
    using System;
    interface IPoint
    {
        // Property signatures:
        int x
        {
            get;
            set;
        }    int y
        {
            get;
            set;
        }
    }class Point : IPoint
    {
        // Fields:
        private int _x;
        private int _y;    // Constructor:
        public Point(int x, int y)
        {
            _x = x;
            _y = y;
        }    // Property implementation:
        public int x
        {
            get
            {
                return _x;
            }        set
            {
                _x = value;
            }
        }    public int y
        {
            get
            {
                return _y;
            }
            set
            {
                _y = value;
            }
        }
    }class MainClass
    {
        static void PrintPoint(IPoint p)
        {
            Console.WriteLine("x={0}, y={1}", p.x, p.y);
        }    static void Main()
        {
            Point p = new Point(2, 3);
            Console.Write("My Point: ");
            PrintPoint(p);
        }
    }
    输出
      
    My Point: x=2, y=3 
      

  11.   

    简单来说虚函数(Virtual)已经包含了也必须包含默认的实现,所以在派生类中可以重新实现也可以不实现这些虚函数。
    抽象函数(abstract)没有提供默认实现,所以在派生类中必须实现这些抽象函数。
    接口中的函数类似于抽象函数,也不提供默认实现,实现接口的类也必须实现这些函数。
    但接口可用于多继承,即,类只能从一个类继承,但可同时实现多个接口。