一、继承
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(); } } }
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(); } } }
二、多态
多态性可以是静态的或动态的。在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。
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(); } } }
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(); } } }
三、接口
接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。
接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。
接口及其成员总是隐式为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(); } } }