* abstract

修饰符。抽象的。描述(类、方法、属性、索引和事件)的实现不完整或未实现。如果一个类是抽象的,表明其只能为一个基类,而不能实例化。只有修饰为 abstract 的类才能具有修饰为 abstract 的成员。派生类必须完整实现其基类中未实现的方法、属性、索引和事件。

下面构建一个基类(Ti)。描述不同的体需要的不同的描述方式。

    /// <summary>
    /// 一个体。基类,必须被其他类继承。
    /// </summary>
    abstract class Ti
        {
        public abstract double TiJi ( ); // 必须被派生类实现的方法(不同的体具有不同的体积计算方式)

        public static string ShuoMing ( ) // 无需被派生类实现的方法(每个体都一致的输出)
            {
            return "我写的漂亮吗……";
            }
        }

下面这个类派生自基类 Ti(正方体),必须实现基类未实现的内容:

    /// <summary>
    /// 正方体。每条棱(边长)均相等的正六面体。
    /// </summary>
    /// <param name="边长">棱的长度</param>
    class ZhengFantTi ( double 边长 ) : Ti
        {
        private readonly double _BianChang = 边长;

        // TiJi 方法是避免编译时错误(CS0534)所必需的,因为继承自 Ti,而基类的 TiJi 未实现。
        public override double TiJi ( )
            {
            return double . Pow (_BianChang , 3 );
            }

        public override string ToString ( )
            {
            return $"边长 {_BianChang} 的正方体({ZhengFantTi . ShuoMing ( )})";
            }
        }

ToString 方法继承自 object,所以抽象类无需声明。

        {
            ZhengFantTi Fang = new ( 1.5 );
            Console . WriteLine ( $"{Fang . ToString ( )}的体积:{Fang . TiJi ( )}" );
        }

上述的控制台程序,产生下列输出:
边长 1.5 的正方体(我写的漂亮吗……)的体积:3.375

抽象类的某些内容可以是具体的,派生类直接用即可(无法 override)。例如上述的基类中的 ShuoMing 即被派生类 ToString 直接用了。

sealed 修饰符表明该类无法被继承,不能与 abstract 共用。


抽象方法和属性:

上述基类 Ti 中有抽象方法,抽象属性类似。必须存在于抽象类中。抽象方法是虚拟的,所以不能使用 static 和 virtual 修饰符,方法本身签名之后就是分号结尾。派生类中,均使用 override 修饰符重写基类中的抽象方法和属性。

抽象接口

抽象类如果实现接口,那就必须为所有接口成员提供实现。有可能把接口方法映射到抽象方法上:

    interface IJK
        {
        void FF ( ) ;
        }

    abstract class Ljk : IJK
        {
        public abstract void FF ( ) ;
        }

重写属性

下面的例子通过重写属性和方法实现:

    /// <summary>
    /// 一对整数的基类,描述了分别为 1000 和 150 的两个 int
    /// </summary>
    abstract class ZhengShuDui基类
        {
        protected int _x = 1000 , _y = 150;
        
        // 必须被派生类重写的处理方法
        public abstract void ChuLiFangFa ( ) ;

        /// <summary>
        /// 必须被重写的整数对中的第一个(X)
        /// </summary>
        public abstract int X
            {
            get;
            }

        /// <summary>
        /// 必须被重写的整数对中的第二个(Y)
        /// </summary>
        public abstract int Y
            {
            get;
            }
        }
    /// <summary>
    /// 派生的整数对类,添加了处理方式和属性的代码。
    /// </summary>
    class ZhengShuDui派生 : ZhengShuDui基类
        {
        /// <summary>
        /// 重写的基类中的处理方法(X 加上 10,Y 减去 10)
        /// </summary>
        public override void ChuLiFangFa ( )
            {
            _x += 10;
            _y -= 10;
            }

        /// <summary>
        /// 重写的 X 属性(X 乘以 10)
        /// </summary>
        public override int X
            {
            get
                {
                return _x * 10;
                }
            }

        /// <summary>
        /// 重写的 Y 属性(Y 除以 10)
        /// </summary>
        public override int Y
            {
            get
                {
                return _y / 10;
                }
            }
        }

如果对 ZHSs(声明自 ZhengShuDui派生 的对象)的 X 和 Y 属性输出得到:
X = 10100,Y = 14

形状

现在我们要创建形状类了。这个形状包括边界和颜色。

    /// <summary>
    /// 形状,描述一个封闭的形状并有颜色。
    /// </summary>
    public abstract class XingZhuang
        {
        public string YanSe
            {
            get;
            set;
            }

        protected XingZhuang ( string 颜色 )
            {
            YanSe = 颜色 ;
            Console . WriteLine ( $"创建一个 {YanSe} 颜色的形状。" );
            }

        public abstract double 面积 ( );
        }

继承自 形状类 的 方形:

    /// <summary>
    /// 方形形状,即正方形。
    /// </summary>
    public class Fang ( string 颜色 , double 边长 ) : XingZhuang( 颜色 )
        {
        public double BianChang
            {
            get;
            set;
            } = 边长;

        public override double 面积 ( )
            {
            return double . Pow ( BianChang , 2 );
            }
        }

调用:

        Fang f = new ( "红" , 3.65 );
        Console . WriteLine ( $"{f . YanSe} 正方形的面积:{f . 面积 ( )}" );

输出:
红色 正方形的面积:13.3225

  • 即使无法创建抽象类的对象,但是它仍然可以有构造函数。此构造函数通常为 protected,这意味着只能从派生类中访问。 在这种情况下,XingZhuang 构造函数采用 YanSe 参数并初始化 YanSe 属性。 它还将消息输出到控制台。public class Fang ( string 颜色 , double 边长 ) : XingZhuang( 颜色 ) 部件调用基类的构造函数(XingZhuang),并将 颜色 参数传递给它。
  • 在 XingZhuang 类中,定义的构造函数采用 颜色 作为参数 protected XingZhuang ( string 颜色 )。这意味着 C# 不再自动提供默认无参数构造函数。将默认值设置为颜色 protected Shape(string color="绿") 将允许在派生类中省略:base(color) 表达式,仍会调用此类构造函数 protected Shape(string color="绿"),并将颜色设置为绿色。

兔子码农
2 声望1 粉丝

一个酒晕子


引用和评论

0 条评论