zoukankan      html  css  js  c++  java
  • 抽象类和接口

    一、抽象类

    含有abstract修饰符的类即为抽象类,含有abstract修饰符的方法为抽象方法。

    sealed关键字不能和abstract一起用,因为一个密封类不能够被继承。

    如果类包含了抽象函数,则该类也是抽象的,必须声明为抽象。

    抽象类不能被实例化。抽象类可以包括抽象方法和普通方法。

    抽象方法只能声明于抽象类中,且不包含任何实现。所有的抽象方法,必须在非抽象的派生类中被重写。

    另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法,也可以选择不覆盖

    二、接口

    1.接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。

    除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员、字段

    一个类可以直接实现多个接口,但只能直接继承一个类(包括抽象类)。 

    接口和接口之间是继承关系,而非实现关系,如下。

    public interface Interface2 extends Interface1{  
        public int a = 1;  
        public void method2();  
    }  

    2.使用接口可以使继承它的类命名统一规范,易于维护

    namespace ConsoleApplication1
    {
        interface IPrint1
        {    //接口中的成员可以包括方法,属性,索引器,事件
            //接口中不能包含常量,静态成员,构造函数,析构函数,字段
            //接口中的所有成员,不能有new、public、protected、internal、private等修饰符
            //接口中不能使用new操作符声明一个接口的实例对象
            //接口一旦被继承,子类需要实例化接口中所有成员
            void Print1();//定义了Print方法,但没有实现方法体
        }
    
        interface IPrint2
        {
            void Print2();
        }
    
        class A : IPrint1,IPrint2//接口是一种引用类型,通过接口可以实现多重继承 ---> 一个类可以直接实现多个接口,接口之间用逗号隔开
        {
            public void Print1()
            {
                System.Console.WriteLine("A1");
            }
            public void Print2()
            {
                System.Console.WriteLine("A2");
            }
        }
    
        class B : IPrint1,IPrint2
        {
            public void Print1()
            {
                System.Console.WriteLine("B1");
            }
            public void Print2()
            {
                System.Console.WriteLine("B2");
            }
        }
    
        class AppMain//派生类必须实现接口中的所有成员
        {
            public static void Print1(IPrint1 obj1)
            {
                obj1.Print1();
            }
            public static void Print2(IPrint2 obj2)
            {
                obj2.Print2();
            }
            public static void Main()
            {
                Print1(new A());
                Print1(new B());
                Print2(new A());
                Print2(new B());
            }
        }
    }

    --------------------------------------------------------------------------
    不能初始化的类被叫做抽象类

    namespace ConsoleApplication1
    {
        abstract class MyAbs//sealed关键字不能和abstract一起用,因为一个密封类不能够被抽象
        {
            //抽象类中可以包括抽象方法,和非抽象方法(已实现的方法)
            public void NonAbMethod()
            {
                Console.WriteLine("Non-Abstract Method");
                Console.ReadKey();
            }
            public abstract void AbMethod();//只声明了抽象方法,但没有方法体
            public abstract void AbMethod2();
        }
    
        class MyClass : MyAbs//派生类必须重写抽象类中的所有的方法
        {
            public override void AbMethod()
            {
                Console.WriteLine("Abstract method");
                Console.ReadKey();
            }
            public override void AbMethod2()
            {
                Console.WriteLine("Abstract method2");
                Console.ReadKey();
            }
        }
    
        class MyClient
        {
            //派生类必须实现所有的的基类抽象方法
            public static void Main()
            {
                            //MyAbs mb = new MyAbs();//抽象类不能直接创建实例
                MyClass mc = new MyClass();//
                mc.NonAbMethod();
                mc.AbMethod();
                mc.AbMethod2();
            }
        }
    }

    --------------------------------------------------------------------------
    相同点:
    1.都可以被继承

    2.都不能被直接实例化

    3.都包含未实现的方法声明

    4.派生类都必须实现接口和抽象类的未实现的方法
    --------------------------------------------------------------------------
    区别:
    1.抽象类中可以有非抽象的方法(可以加代码逻辑),不需要重写所有的方法,只需重写抽象方法。
    但接口不能,没有方法体,派生类必须重写接口中的所有方法。

    2.抽象类只能被单一继承,接口可以被多重实现(派生类可以实现多个接口)

    3. 抽象类中的抽象方法的访问类型可以是public,protected,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

    4.抽象类中可以包含静态方法,接口中不能包含静态方法

    5.    ①在接口中 不可以有构造方法

    在接口里写入构造方法时,编译器提示:Interfaces cannot have constructors。

    A. 构造方法用于初始化成员变量,但是接口成员变量是常量,无需修改。接口是一种规范,被调用时,主要关注的是里边的方法,而方法是不需要初始化的,

    B. 类可以实现多个接口,若多个接口都有自己的构造器,则不好决定构造器链的调用次序

    C. 构造器是属于类自己的,不能继承。因为是纯虚的,接口不需要构造器。

      ②在抽象类中 可以有构造方法。

    在抽象类中可以有构造方法,只是不能直接创建抽象类的实例对象,但实例化子类的时候,就会初始化父类,不管父类是不是抽象类都会调用父类的构造方法,初始化一个类,先初始化父类。

    --------------------------------------------------------------------------
    用途区别:

    1.抽象类是提取具体类的公因式,而接口是为了将一些不相关的类“杂凑”成一个共同的群体。

    2.所有代码共有和可扩展性考虑,尽量使用Abstract Class。

    3.当在差异较大的对象间寻求功能上的共性时,使用接口;当共性较多的对象间寻求功能上的差异时,使用抽象类。

    4.如果要创建组件的多个版本,建议使用抽象类。如果设计小而简练的功能块,则使用接口。









  • 相关阅读:
    在TreeView控件节点中显示图片
    PAT 甲级 1146 Topological Order (25 分)
    PAT 甲级 1146 Topological Order (25 分)
    PAT 甲级 1145 Hashing
    PAT 甲级 1145 Hashing
    PAT 甲级 1144 The Missing Number (20 分)
    PAT 甲级 1144 The Missing Number (20 分)
    PAT 甲级 1151 LCA in a Binary Tree (30 分)
    PAT 甲级 1151 LCA in a Binary Tree (30 分)
    PAT 甲级 1149 Dangerous Goods Packaging
  • 原文地址:https://www.cnblogs.com/chrisghb8812/p/6089367.html
Copyright © 2011-2022 走看看