继承
<访问修饰符> class <基类>
{
...
}
class <派生类> : <基类>
{
...
}
关于函数的初始化:
- 如果子类没有显式地调用基类的构造函数,则编译器会自动调用基类的无参构造函数。
- 如果基类没有无参构造函数,子类在构造时会编译时报错。
- 因此,在子类构造函数中要显示调用基类的构造函数,以确保继承来的属性被正确地初始化。
- 当然,子类的构造函数也可以有自己的逻辑和参数列表,只是在执行子类构造函数之前,基类的构造函数先执行完成。
具体实例在多态展示
多态性
using System;
using System.Collections.Generic;
public class Shape//基类的构建
{
public int X { get; private set; }
public int Y { get; private set; }
public int Height { get; set; }
public int Width { get; set; }
// 虚方法
public virtual void Draw()
{
Console.WriteLine("执行基类的画图任务");
}
}
class Circle : Shape//子类的构建1
{
public override void Draw() //在子类当中重载已经定义的Draw方法,在基类当中他是虚方法
{
Console.WriteLine("画一个圆形");
base.Draw();
}
}
class Rectangle : Shape//子类的构建2
{
public override void Draw()//在子类当中重载……
{
Console.WriteLine("画一个长方形");
base.Draw();
}
}
class Triangle : Shape//子类的构建3
{
public override void Draw()//在子类当中重载……
{
Console.WriteLine("画一个三角形");
base.Draw();
}
}
class Program//主程序
{
static void Main(string[] args)
{
// 创建一个 List<Shape> 对象,并向该对象添加 Circle、Triangle 和 Rectangle
var shapes = new List<Shape>//将三个子类实例化,保存在List当中
{
new Rectangle(),
new Triangle(),
new Circle()
};
// 使用 foreach 循环对该列表的派生类进行循环访问,并对其中的每个 Shape 对象调用 Draw 方法
foreach (var shape in shapes)
{
shape.Draw();
}
Console.WriteLine("按下任意键退出。");
Console.ReadKey();
}
}
注释:
- 基类当中的非虚方法不能在子类当中用override重载
- 基类当中的虚方法可以在子类通过base.function()调用
接口
using System;
interface ILogger
{
void Log(string message);
}
class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}
class Program
{
static void Main(string[] args)
{
ConsoleLogger consoleLogger = new ConsoleLogger();
ILogger logger = consoleLogger; // 将 ConsoleLogger 的实例转换为 ILogger 接口类型的引用
logger.Log("Hello, World!"); // 通过 ILogger 接口类型的引用来调用实现类中的方法
}
}
由于 ConsoleLogger 实现了 ILogger 接口,因此它的实例可以赋值给 ILogger 接口类型的变量。
因此,我们可以通过 ILogger 接口类型的变量来调用实现类中的方法,
而不是通过具体类的实例来调用。
命名空间
命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式。在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突。
我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。
下面的程序演示了命名空间的用法:
using System;
namespace first_space
{
class namespace_cl
{
public void func()
{
Console.WriteLine("Inside first_space");
}
}
}
namespace second_space
{
class namespace_cl
{
public void func()
{
Console.WriteLine("Inside second_space");
}
}
}
class TestClass
{
static void Main(string[] args)
{
first_space.namespace_cl fc = new first_space.namespace_cl();
second_space.namespace_cl sc = new second_space.namespace_cl();
fc.func();
sc.func();
Console.ReadKey();
}
}
命名空间可以多层嵌套,可以用点运算符直接进行访问,相当于为函数加上前缀,避免重名