14.C# —— 虚方法,new/override,密封类,索引器,接口

目录

[一、虚方法 virtual](#一、虚方法 virtual)

[1. 核心概念](#1. 核心概念)

示例代码

[二、new 和 override 重写区别(重点)](#二、new 和 override 重写区别(重点))

[1. new 关键字:隐藏父类方法](#1. new 关键字:隐藏父类方法)

[2. override 关键字:覆盖父类虚方法](#2. override 关键字:覆盖父类虚方法)

示例演示

三、四类特殊类:abstract/sealed/static/partial

[1. abstract 抽象类](#1. abstract 抽象类)

[2. sealed 密封类](#2. sealed 密封类)

[3. static 静态类](#3. static 静态类)

[4. partial 部分类](#4. partial 部分类)

[四、索引器 this \[\]](#四、索引器 this [])

[1. 定义作用](#1. 定义作用)

[2. 特性:支持重载](#2. 特性:支持重载)

[案例 1:多参数重载索引器](#案例 1:多参数重载索引器)

[案例 2:动态扩容索引器](#案例 2:动态扩容索引器)

[五、接口 interface](#五、接口 interface)

[1. 基础规则](#1. 基础规则)

[2. 继承类 + 实现多接口](#2. 继承类 + 实现多接口)

六、知识点汇总小结


一、虚方法 virtual

1. 核心概念

virtual修饰父类普通方法,拥有方法体;子类可选重写,不重写则调用父类原有逻辑,是实现多态的基础。

虚方法 VS 抽象方法

  1. 虚方法写在普通类,抽象方法只能在abstract抽象类;
  2. 虚方法有方法体,抽象方法无方法体;
  3. 虚方法子类可选择不重写,抽象方法子类必须全部实现
  4. 虚方法子类用override/new改写,抽象方法只能override

示例代码

cs 复制代码
public class People
{
    public string Name { get; set; }
    public virtual void SayHellow()
    {
        Console.WriteLine("People打招呼");
    }
}
//子类override重写虚方法
public class China : People
{
    public override void SayHellow()
    {
        Console.WriteLine("吃了吗,抽个烟");
    }
}
public class Japan : People
{
    public override void SayHellow()
    {
        Console.WriteLine("汪汪");
    }
}

二、new 和 override 重写区别(重点)

1. new 关键字:隐藏父类方法

子类新建同名方法,父子方法互相独立互不覆盖调用规则由变量声明类型决定

  • 父类变量接收子类对象 → 调用父类方法;
  • 子类变量接收子类对象 → 调用子类 new 新方法。

2. override 关键字:覆盖父类虚方法

直接重写替换父类虚方法,无论变量声明是父类还是子类,全部执行子类重写方法

示例演示

cs 复制代码
public class People
{
    public virtual void Test1() => Console.WriteLine("People的Test1");
    public virtual void Test3() => Console.WriteLine("People的Test3");
}
public class Student : People
{
    //new隐藏
    public new void Test1() => Console.WriteLine("Student的Test1");
    //override覆盖
    public override void Test3() => Console.WriteLine("Student的Test3");
}

//调用测试
People p1 = new Student();
Student s1 = new Student();
p1.Test1();//父类方法(new特性)
p1.Test3();//子类方法(override特性)

三、四类特殊类:abstract/sealed/static/partial

1. abstract 抽象类

不能实例化,设计目的仅用于被继承,可包含普通方法 + 抽象方法。

cs 复制代码
abstract class Test { }

2. sealed 密封类

可以实例化,禁止被任何类继承

cs 复制代码
sealed class Test1 { }

3. static 静态类

不能实例化,所有成员必须全部 static 修饰

cs 复制代码
static class Test2
{
    public static int Age { get; set; }
}

4. partial 部分类

partial class拆分一个类到多个 cs 文件,命名空间、类名必须完全一致,编译时编译器自动合并为单个完整类。

cs 复制代码
partial class Test3 { }

四、索引器 this \[\]

1. 定义作用

普通类默认不能用对象[下标]取值赋值,通过索引器public 返回值 this[参数]{get;set;} ,让实例像数组一样通过[]访问内部数据。

2. 特性:支持重载

同一个类可以定义多组不同参数的索引器(int 数字、string 字符串、自定义实体)。

案例 1:多参数重载索引器

cs 复制代码
class ClassRoom
{
    public List<Student> list = new List<Student>();
    public void Add(Student stu) => list.Add(stu);

    //int下标索引器
    public Student this[int index]
    {
        get => list[index];
        set => list[index] = value;
    }
    //字符串姓名索引器
    public Student this[string name]
    {
        get => list.Find(s => s.Name == name);
    }
    //实体参数索引器,返回下标
    public int this[Student stu]
    {
        get => list.FindIndex(s => s.Name == stu.Name);
    }
}
class Student { public string Name { get; set; } public int Age { get; set; } }
//使用
ClassRoom room = new ClassRoom();
room.Add(new Student { Name = "李四", Age = 20 });
Student s = room["李四"];
int idx = room[new Student { Name = "李四", Age = 20 }];

案例 2:动态扩容索引器

set 访问时下标超出数组长度,自动新建数组复制数据、实现动态扩容:

cs 复制代码
public class Student
{
    private string[] names = new string[4];
    public Student(string[] s) => names = s;
    public string this[int index]
    {
        get => names[index];
        set
        {
            if (index >= names.Length)
            {
                string[] newArr = new string[names.Length + 1];
                Array.Copy(names, newArr, names.Length);
                newArr[index] = value;
                names = newArr;
            }
            else names[index] = value;
        }
    }
}

五、接口 interface

1. 基础规则

  1. 关键字interface,规范命名以I开头;
  2. 接口不能实例化 ,成员默认public,不能手动加访问修饰符;
  3. 接口只写属性、方法声明,没有实现体
  4. 一个类可以同时实现多个接口,必须实现全部接口成员。

2. 继承类 + 实现多接口

子类继承父类同时实现新接口时,若父类已存在同名成员,可用new重写接口属性。

cs 复制代码
interface IBook
{
    int Id { get; set; }
    void F1();
}
interface IPaper
{
    string color { get; set; }
    void F2();
}
//类实现多个接口
class Book : IBook, IPaper
{
    public int Id { get; set; }
    public string color { get; set; }
    public void F1() { }
    public void F2() { }
    public string StudentId { get; set; }
}
interface IPeople { string StudentId { get; set; } }
//继承Book + 实现IPeople,new重写同名属性
class SmallBook : Book, IPeople
{
    public new string StudentId { get; set; }
}

六、知识点汇总小结

  1. virtual虚方法用于子类可选重写,是多态实现前提;
  2. new隐藏方法看变量类型,override覆盖方法永远走子类;
  3. abstract 不能实例化、sealed 不能继承、static 不能实例化、partial 拆分多文件;
  4. 索引器this[]让对象支持[]访问,支持多参数重载;
  5. 接口定规范、多实现、无实例,类实现接口必须落地全部成员。
相关推荐
糖果店的幽灵1 小时前
LangChain 1.3 完全教程:从入门到精通-Part 11: Tools(工具系统)
开发语言·langchain·c#
专注VB编程开发20年6 小时前
python翻译网页HTML的难题
python·c#·html
z落落6 小时前
C# 抽象类(abstract)
java·开发语言·c#
unityのkiven8 小时前
工作分享1(26.5.27):基于栈实现全局返回逻辑通用架构设计(适配异步 + 确认弹窗)
游戏·unity·c#·客户端架构
z落落8 小时前
C# 多态 + 函数重载(静态多态)+运算符重载
开发语言·c#
Fms_Sa8 小时前
分治法—最大子段问题
算法·c#
rick9778 小时前
C# 动态对象实战:用 DynamicObject 打造你的"万能插件架构"
c#
玩c#的小杜同学9 小时前
未来 AI 会装进电脑里吗?本地 AI、AI PC 和企业隐私计算
人工智能·微软·c#·电脑·英伟达
荔枝吻9 小时前
【保姆级喂饭教程】Inno Setup下载安装、添加中文、打包、自动化教程
c#·vs·inno setup