目录
[一、虚方法 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 抽象方法
- 虚方法写在普通类,抽象方法只能在
abstract抽象类; - 虚方法有方法体,抽象方法无方法体;
- 虚方法子类可选择不重写,抽象方法子类必须全部实现;
- 虚方法子类用
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. 基础规则
- 关键字
interface,规范命名以I开头; - 接口不能实例化 ,成员默认
public,不能手动加访问修饰符; - 接口只写属性、方法声明,没有实现体;
- 一个类可以同时实现多个接口,必须实现全部接口成员。
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; }
}
六、知识点汇总小结
virtual虚方法用于子类可选重写,是多态实现前提;new隐藏方法看变量类型,override覆盖方法永远走子类;- abstract 不能实例化、sealed 不能继承、static 不能实例化、partial 拆分多文件;
- 索引器
this[]让对象支持[]访问,支持多参数重载; - 接口定规范、多实现、无实例,类实现接口必须落地全部成员。