继承、多态、接口

一、继承
1、基类和派生类

C# 不支持类的多重继承。但是支持接口的多重继承。
继承是可以传递的。定义要从其他类派生的类时,派生类会隐式获得基类的所有成员(除了其构造函数和终结器)。派生类因而可以重用基类中的代码,而无需重新实现。在派生类中,可以添加更多成员。通过这种方法,派生类可扩展基类的功能。

示例:

using System;
using System.Diagnostics;

namespace Test
{
    class Program
    {
        class Shape
        {
            protected int _height;
            protected int _weight;
            public void SetHeight(int h) => _height = h;
            public void SetWeight(int w) => _weight = w;
        }

        class Rectangle : Shape
        {
            public int GetArea()
            {
                return _height * _weight;
            }
        }
        static void Main(string[] args)
        {
            Rectangle obj = new Rectangle();
            obj.SetHeight(10);
            obj.SetWeight(20);
            Console.WriteLine($"Area={obj.GetArea()}");
            Console.ReadLine();
        }
    }
}
View Code

2、基类的初始化

派生类继承了基类的成员变量和成员方法。因此父类对象应在子类对象创建之前被创建。可以在成员初始化列表中进行父类的初始化。

示例:

using System;
using System.Diagnostics;

namespace Test
{
    class Program
    {
        class Shape
        {
            protected int _height;
            protected int _weight;
            public Shape() { }
            public Shape(int h, int w) { _height = h;_weight = w; }
            public void SetHeight(int h) => _height = h;
            public void SetWeight(int w) => _weight = w;
        }

        class Rectangle : Shape
        {
            public Rectangle():base(10, 10) { }
            public int GetArea()
            {
                return _height * _weight;
            }
        }
        static void Main(string[] args)
        {
            Rectangle obj = new Rectangle();
            Console.WriteLine($"Area={obj.GetArea()}");
            Console.ReadLine();
        }
    }
}
View Code

二、多态

多态性可以是静态的或动态的。在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。

1、静态多态性

在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。C# 提供了两种技术来实现静态多态性。分别为:函数重载、运算符重载。

2、动态多态性

动态多态性是通过抽象类和虚方法实现的。

抽象方法和虚方法的区别:

  • 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。
  • 抽象方法只能在抽象类中声明,虚方法不是。如果类包含抽象方法,那么该类也是抽象的,也必须声明类是抽象的。
  • 抽象方法必须在派生类中重写,这一点和接口类似。虚方法是已经实现了的,可以被子类覆盖,也可以不覆盖,取决于需求。

1)抽象类

用关键字 abstract 创建抽象类,用于提供接口的部分类的实现。当一个派生类继承自该抽象类时,实现即完成。抽象类包含抽象方法,抽象方法可被派生类实现。派生类具有更专业的功能。

抽象类的一些规则:

  • 您不能创建一个抽象类的实例。
  • 您不能在一个抽象类外部声明一个抽象方法。
  • 通过在类定义前面放置关键字 sealed,可以将类声明为密封类。当一个类被声明为 sealed 时,它不能被继承。抽象类不能被声明为 sealed。

示例:

using System;
using System.Diagnostics;

namespace Test
{
    class Program
    {
        public abstract class Shape
        {
            protected int _x;
            protected int _y;
            public Shape(int x, int y) { _x = x;_y = y; }
            public abstract void Area();
        }

        class Rectangle : Shape
        {
            public Rectangle():base(10, 10) { }
            public override void Area()
            {
                Console.WriteLine($"Rectangle 类的面积:{_x * _y}");
            }
        }

        class Square : Shape
        {
            public Square() : base(20, 20) { }
            public override void Area()
            {
                Console.WriteLine($"Square 类的面积:{_x * _y}");
            }
        }

        public static void ShowArea(Shape obj)
        {
            obj.Area();
        }

        static void Main(string[] args)
        {
            ShowArea(new Rectangle());
            ShowArea(new Square());
            Console.ReadLine();
        }
    }
}
View Code

2)虚方法

当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法。虚方法是使用关键字 virtual 声明的。虚方法可以在不同的继承类中有不同的实现。对虚方法的调用是在运行时发生的。

示例:

using System;
using System.Diagnostics;

namespace Test
{
    class Program
    {
        public class Shape
        {
            protected int _x;
            protected int _y;
            public Shape(int x, int y) { _x = x;_y = y; }
            public virtual void Area()
            {
                Console.WriteLine($"Shape 类的面积:{_x * _y}");
            }
        }

        class Rectangle : Shape
        {
            public Rectangle():base(10, 10) { }
            public override void Area()
            {
                Console.WriteLine($"Rectangle 类的面积:{_x * _y}");
            }
        }

        class Square : Shape
        {
            public Square() : base(20, 20) { }
            public override void Area()
            {
                Console.WriteLine($"Square 类的面积:{_x * _y}");
            }
        }

        public static void ShowArea(Shape obj)
        {
            obj.Area();
        }

        static void Main(string[] args)
        {
            ShowArea(new Rectangle());
            ShowArea(new Square());
            Console.ReadLine();
        }
    }
}
View Code

三、接口

接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。
接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。
接口及其成员总是隐式为public的。
接口使用的注意事项:

  • 接口方法不能用public abstract等修饰。接口内不能有字段变量,构造函数。
  • 接口内可以定义属性(有get和set的方法)。如string color { get ; set ; }这种。
  • 实现接口时,必须和接口的格式一致。
  • 必须实现接口的所有方法。

示例:

using System;
using System.Diagnostics;

namespace Test
{
    class Program
    {
        public interface IShape
        {
            int GetHeight { get; set; }
            int GetWeight { get; set; }
            void GetArea();
        }

        public class Rectangle : IShape
        {
            private int _height;
            private int _weight;
            public int GetHeight { get => _height; set => _height=value; }
            public int GetWeight { get => _weight; set => _weight=value; }

            public void GetArea()
            {
                Console.WriteLine($"Rectangle: Area={_height * _weight}");
            }
        }

        public class Square : IShape
        {
            private int _height;
            private int _weight;
            public int GetHeight { get => _height; set => _height = value; }
            public int GetWeight { get => _weight; set => _weight = value; }

            public void GetArea()
            {
                Console.WriteLine($"Square: Area={_height * _weight}");
            }
        }

        public static void Show(IShape obj)
        {
            obj.GetArea();
        }

        static void Main(string[] args)
        {
            Rectangle rect = new Rectangle();
            rect.GetHeight = 10;
            rect.GetWeight = 10;
            Show(rect);
            Square sq = new Square();
            sq.GetHeight = 20;
            sq.GetWeight = 20;
            Show(sq);
            Console.ReadLine();
        }
    }
}
View Code

原文地址:https://www.cnblogs.com/ACGame/p/10963025.html