zoukankan      html  css  js  c++  java
  • C# abstract

    Abstract:

      1、用途:提供一个可供多个派生类共享的通用基类定义。

      2、抽象类也可以定义抽象方法,方法是将关键字 abstract 添加到方法的返回类型的前面(抽象方法没有实现,所以方法定义后面是分号,而不是常规的方法块),

         抽象类的派生类必须实现所有抽象方法。当抽象类从基类继承虚方法时,抽象类可以使用抽象方法重写该虚方法,

    public class D
    {
      public virtual void DoWork(int i)
      {
        // Original implementation.
      }
    }
     
    public abstract class E : D
    {
      public abstract override void DoWork(int i);
    }
     
    public class F : E
    {
      public override void DoWork(int i)
      {
        // New implementation.
      }
    }
    public abstract class Shape
    {
      private string name;
     
      public Shape(string s)
      {
        // calling the set accessor of the Id property.
        Id = s;
      }
     
      public string Id
      {
        get
        {
          return name;
        }
     
        set
        {
          name = value;
        }
      }
     
      // Area is a read-only property - only a get accessor is needed:
      public abstract double Area
      {
        get;
      }
     
      public override string ToString()
      {
        return Id + " Area = " + string.Format("{0:F2}", Area);
      }
    }

    public class Square : Shape
    {
      private int side;
     
      public Square(int side, string id)
        : base(id)
      {
        this.side = side;
      }
     
      public override double Area
      {
        get
        {
          // Given the side, return the area of a square:
          return side * side;
        }
      }
    }
     
    public class Circle : Shape
    {
      private int radius;
     
      public Circle(int radius, string id)
        : base(id)
      {
        this.radius = radius;
      }
     
      public override double Area
      {
        get
        {
          // Given the radius, return the area of a circle:
          return radius * radius * System.Math.PI;
        }
      }
    }
     
    public class Rectangle : Shape
    {
      private int width;
      private int height;
     
      public Rectangle(int width, int height, string id)
        : base(id)
      {
        this.width = width;
        this.height = height;
      }
     
      public override double Area
      {
        get
        {
          // Given the width and height, return the area of a rectangle:
          return width * height;
        }
      }
    }
    
    
    class TestClass
    {
      static void Main()
      {
        Shape[] shapes =
        {
          new Square(5, "Square #1"),
          new Circle(3, "Circle #1"),
          new Rectangle( 4, 5, "Rectangle #1")
        };
     
        System.Console.WriteLine("Shapes Collection");
        foreach (Shape s in shapes)
        {
          System.Console.WriteLine(s);
        }
      }
    }
    //输出:
    //Shapes Collection
    //Square #1 Area = 25.00
    //Circle #1 Area = 28.27
    //Rectangle #1 Area = 20.00

      注:

        1、C#中Abstract和Virtual

          一、Virtual方法(虚方法)

               virtual 关键字用于在基类中修饰方法。virtual的使用会有两种情况:

                 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。

                 情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。

          二、Abstract方法(抽象方法)

               abstract关键字只能用在抽象类中修饰方法,并且没有具体的实现。抽象方法的实现必须在派生类中使用override关键字来实现。

        2、接口和抽象类:

           最本质的区别:抽象类是一个不完全的类,是对对象的抽象,而接口是一种行为规范。

           1、抽象类中可以有非抽象方法;

            但接口中只提供一些方法规约,不提供方法主体,方法不能用public abstract等修饰,无字段变量,无构造函数。且实现interface的类必须实现接口的各个方法。

          2、抽象类虽不能实例化(然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例),但可以有构造函数,抽象类的构造函数用来初始化抽象类的一些字段,而这一切都在抽象类的派生类实例化之前发生。不仅如此,抽线类的构造函数还有一种巧妙应用:就是在其内部实现子类必须执行的代码。

          

    class Program
        {
            static void Main(string[] args)
            {
                Employee employee = new Employee();
                Console.WriteLine(employee.ID);
                Console.ReadKey();
            }
        }
        public abstract class Base
        {
            private Guid _id;
            public Base()
            {
                this._id = Guid.NewGuid();
            }
            public Guid ID
            {
                get { return this._id; }
            }
        }
        public class Employee : Base
        {
            
        }

        3、一个类只能继承一个抽象类,但可以实现多个接口。

        4、当一个类继承了一个抽象类,它必须要重写父类抽象类中的抽象方法,如果不去重写父类抽象方法的实例,那么这个类也是抽象类(这个抽象子类,直到重写这个抽象方法的实例为止,才能摆脱抽象的命运)。

            实现接口也必须实现接口中的每个行为。

    一个类可以同时继承多个“接口”,但只能继承一个“抽象类”

      

        

    public class Square : Shape
    {
      private int side;
     
      public Square(int side, string id)
        : base(id)
      {
        this.side = side;
      }
     
      public override double Area
      {
        get
        {
          // Given the side, return the area of a square:
          return side * side;
        }
      }
    }
     
    public class Circle : Shape
    {
      private int radius;
     
      public Circle(int radius, string id)
        : base(id)
      {
        this.radius = radius;
      }
     
      public override double Area
      {
        get
        {
          // Given the radius, return the area of a circle:
          return radius * radius * System.Math.PI;
        }
      }
    }
     
    public class Rectangle : Shape
    {
      private int width;
      private int height;
     
      public Rectangle(int width, int height, string id)
        : base(id)
      {
        this.width = width;
        this.height = height;
      }
     
      public override double Area
      {
        get
        {
          // Given the width and height, return the area of a rectangle:
          return width * height;
        }
      }
    }
     
     
     

    接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。

    下面比较一下两者的语法区别:

    1.抽象类可以有构造方法,接口中不能有构造方法。

    2.抽象类中可以有普通成员变量,接口中没有普通成员变量

    3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

    4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

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

    6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。

    7. 一个类可以实现多个接口,但只能继承一个抽象类。

         下面接着再说说两者在应用上的区别:

        接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。

        而抽象类在代码实现方面发挥作用,可以实现代码的重用
  • 相关阅读:
    使用ActivityGroup来切换Activity和Layout
    Fragment
    [Java]LeetCode297. 二叉树的序列化与反序列化 | Serialize and Deserialize Binary Tree
    [Swift]LeetCode298. 二叉树最长连续序列 $ Binary Tree Longest Consecutive Sequence
    [Swift]LeetCode296. 最佳开会地点 $ Best Meeting Point
    [Swift]LeetCode294. 翻转游戏之 II $ Flip Game II
    [Swift]LeetCode293. 翻转游戏 $ Flip Game
    [Swift]LeetCode291. 单词模式 II $ Word Pattern II
    [Postman]发出SOAP请求(18)
    [Postman]生成代码段(17)
  • 原文地址:https://www.cnblogs.com/WebApp-DotNet/p/6243853.html
Copyright © 2011-2022 走看看