C# 抽象类学习

之前写了个关于接口学习的blog——C# 接口学习,现在在将对抽象类的学习整理下。

一、什么是抽象类

"一个包含一个或多个纯虚函数的类叫抽象类,抽象类不能被实例化,进一步说一个抽象类只能通过接口和作为其它类的基类使用."- C++ Programming Language by Stroustrup Chapter13.2

在C#中的关键字 abstract 来定义抽象类和抽象方法。

二、抽象类的特点

1、抽象类可以有实现(包括构造函数)。

2、抽象类中可以有成员变量(包括静态成员变量)、属性、常量和静态方法,并且他们可以是非公共的。

3、抽象类可以从另一个类或一个/多个接口派生。

4、一个类只能从一个抽象类派生。

5、抽象类不能用密封(sealed)来修饰,那就意味着类不能被继承,这违反抽象类被继承的原则。

三、抽象方法和虚方法

1、抽象方法

1)使用 abstract 关键字。例如:public abstract bool Write();

2)抽象方法只能在抽象类中声明,抽象方法必须在派生类中重写。

3)抽象方法可以看成是没有实现体(方法体)的虚方法。

ps:如果类中包含抽象方法,则该类必定定义为抽象类,不论是否还包含其它一般方法。

2、虚方法

1)虚方法使用 virtual 关键字。例如:public virtual bool Write()

2)调用虚方法,运行时将确定调用对象是什么类型的实例,并调用适当的覆写的方法。

3)虚方法必须有实现部分(方法体),子类可以覆盖也可以不覆盖,根据实际要求确定。

四、示例

1、基本示例,抽象类中使用抽象方法,抽象方法是一个没有方法体的方法。

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ShapeClass square = new Square();
            int area = square.Area();

            Console.WriteLine(area);

            Console.ReadLine();
        }
    }

    abstract class ShapeClass
    {
        abstract public int Area();
    }

    class Square : ShapeClass
    {
        int x = 6;
        int y = 9;

        public override int Area()
        {
            return x * y;
        }
    }
}

2、包含抽象方法,虚方法和非抽象方法。当某个类继承于抽象类,那么该派生类必须实现基类中所有的抽象方法。虚方法可以实现也可以不实现。

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyAbs class1 = new MyClass1();
            Console.WriteLine("abs method result: "+class1.absMethod());
            Console.WriteLine("general class result: " + class1.method1());
            Console.WriteLine("virtual class result: "+class1.virMethod());

            Console.ReadLine();
        }
    }

    abstract class MyAbs
    {
        abstract public string absMethod();

        public string method1()
        {
            return "This is not a abstract method from MyAbs";
        }

        virtual public string  virMethod()
        {
            return "MyAbs.Virtual";
        }
    }

    class MyClass1 : MyAbs
    {

        public override string absMethod()
        {
            return "I'm MyClass1.I override MyAbs.absMetod.";
        }
    }
}

结果:

image

3、使得派生自抽象类的派生类同样是抽象类,可以通过不完全实现抽象类的方法实现。

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyAbs class2 = new MyClass2();
            Console.WriteLine(class2.AbsMethod_1());
            Console.WriteLine(class2.AbsMethod_2());

            Console.ReadLine();
        }
    }

    abstract class MyAbs
    {
        abstract public string AbsMethod_1();
        abstract public string AbsMethod_2();        
    }

    abstract class MyClass1 : MyAbs
    {
        public override string AbsMethod_1()
        {
            return "This is MyClass1.AbsMethod_1()";
        }
    }

    class MyClass2 : MyClass1
    {
        public override string AbsMethod_2()
        {
            return "This is MyClass1.AbsMethod_2()";
        }
    }
}

结果:

image

4、抽象类可以从接口继承。我们可以为接口中的方法添加实现,也可以将他们安在抽象方法中。

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            Console.WriteLine(myClass.interfaceMethod_1());
            Console.WriteLine(myClass.interfaceMethod_2());

            Console.ReadLine();
        }
    }

    interface MyInterface
    {
        string interfaceMethod_1();
        string interfaceMethod_2();
    }
    
    abstract class MyAbs : MyInterface
    {
        public string interfaceMethod_1()
        {
            return "This is MyAbs.I realize interfaceMethod #1";
        }

        public abstract string interfaceMethod_2();
    }

    class MyClass:MyAbs
    {

        public override string interfaceMethod_2()
        {
            return "This is MyClass.I realize the interfaceMethod #2";
        }
    }
}

结果:

image

 

Ok,目前,将接口、抽象类。还有虚方法,抽象方法大概复习了一边。接下来要将接口和抽象类做一个简单的比较。

posted @ 2012-11-17 20:30  地山谦  阅读(199)  评论(0编辑  收藏  举报