做的笔记,具体请参考https://learn.microsoft.com/zh-cn/dotnet/csharp/fundamentals/tutorials/inheritance
本文只是对教程中的例子进行实践。
- namespace Classes;
-
- //只有在基类中嵌套的派生类中,私有成员才可见
- public class A
- {
- private int _value = 10;
-
- public class B : A
- {
- public int GetValue()
- {
- Console.WriteLine("--------B--------");
- return _value;
- }
- }
- }
-
- public class C : A
- {
- public int GetValue()
- {
- //在这里会报错Compiler Error CS0122,
- // CS0122:“"A._value" 不可访问,因为它具有一定的保护级别
- return _value;
- }
- }
Compiler Error CS0122 | Microsoft Learn
此错误可以参考上面的链接
- namespace Classes;
-
- //只有在基类中嵌套的派生类中,私有成员才可见
- public class A
- {
- private int _value = 10;
-
- public class B : A
- {
- public int GetValue()
- {
- Console.WriteLine("--------B--------");
- return _value;
- }
- }
- }
-
-
- public class AccessExample
- {
- public static void Main(string[] args)
- {
- //A.B 是派生自 A 的嵌套类,而 C 则派生自 A。 私有 A._value 字段在 A.B 中可见。
- var b = new A.B();
- Console.WriteLine(b.GetValue());
- }
- }
- // The example displays the following output:
- // 10
- namespace Classes;
-
- //只有在基类中嵌套的派生类中,私有成员才可见
- public class A
- {
- protected int _value = 10;
-
- public class B : A
- {
- public int GetValue()
- {
- Console.WriteLine("--------B--------");
- return _value;
- }
- }
- }
-
- public class C : A
- {
- public int GetValue()
- {
- Console.WriteLine("--------C--------");
- return _value;
- }
- }
-
- public class AccessExample
- {
- public static void Main(string[] args)
- {
- //A.B 是派生自 A 的嵌套类,而 C 则派生自 A。 私有 A._value 字段在 A.B 中可见。
- var b = new A.B();
- Console.WriteLine(b.GetValue());
-
- var c = new C();
- Console.WriteLine(c.GetValue());
- }
- }
- // The example displays the following output:
- //--------B--------
- //10
- //--------C--------
- //10
| Public | 访问不受到限制 |
| Protected | 允许本类以及派生类进行访问 |
| Internal | 访问仅限于当前程序集 |
| Protected Internal | 允许本类或派生类访问,注意比Internal的范围广 |
| Private | 仅允许当前类访问,派生类不能访问 |
基类成员必须标记有 virtual 关键字,才能重写继承的成员。 默认情况下,基类成员没有 virtual 标记,因此无法被重写。 标记有 abstract 关键字的基类成员要求派生类必须重写它们。继承仅适用于类和接口。
- namespace Classes
- {
- public class SimpleClass
- { }
- }
- namespace Classes;
-
- using System.Reflection;
-
- public class SimpleClassExample
- {
- public static void Main()
- {
- Type t = typeof(SimpleClass);
- BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
- BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
- MemberInfo[] members = t.GetMembers(flags);
- Console.WriteLine($"Type {t.Name} has {members.Length} members: ");
- //Type SimpleClass has 9 members:
- foreach (MemberInfo member in members)
- {
- string access = "";
- string stat = "";
- var method = member as MethodBase;
- if (method != null)
- {
- if (method.IsPublic)
- access = " Public";
- else if (method.IsPrivate)
- access = " Private";
- else if (method.IsFamily)
- access = " Protected";
- else if (method.IsAssembly)
- access = " Internal";
- else if (method.IsFamilyOrAssembly)
- access = " Protected Internal ";
- if (method.IsStatic)
- stat = " Static";
- }
- string output = $"{member.Name} ({member.MemberType}): {access}{stat}, Declared by {member.DeclaringType}";
- Console.WriteLine(output);
- //公共 GetType 方法:返回表示 SimpleClass 类型的 Type 对象。
- //GetType(Method): Public, Declared by System.Object
-
- //受保护 MemberwiseClone 方法:创建当前对象的浅表复制。
- //MemberwiseClone(Method): Protected, Declared by System.Object
-
- //受保护 Finalize 方法:用于在垃圾回收器回收对象的内存之前释放非托管资源。
- //Finalize(Method): Protected, Declared by System.Object
-
- //公共 ToString 方法将 SimpleClass 对象转换为字符串表示形式,返回完全限定的类型名称。 在这种情况下,ToString 方法返回字符串“SimpleClass”。
- //ToString(Method): Public, Declared by System.Object
-
- //公共实例 Equals(Object) 方法、公共静态 Equals(Object, Object) 方法和公共静态 ReferenceEquals(Object, Object) 方法。 默认情况下,这三个方法测试的是引用相等性;也就是说,两个对象变量必须引用同一个对象,才算相等。
- //Equals(Method): Public, Declared by System.Object
- //Equals(Method): Public Static, Declared by System.Object
- //ReferenceEquals(Method): Public Static, Declared by System.Object
-
- //公共GetHashCode 方法:计算允许在经哈希处理的集合中使用类型实例的值。
- //GetHashCode(Method): Public, Declared by System.Object
- //.ctor(Constructor): Public, Declared by Classes.SimpleClass
- }
- }
- }
从上面的例子中我们可以看到,
.NET 类型系统中的所有类型除了可以通过单一继承进行继承之外,还可以隐式继承自 Object 或其派生的类型。 Object 的常用功能可用于任何类型。
然后可以使用反射(便于检查类型的元数据,从而获取此类型的相关信息),获取 SimpleClass 类型的成员列表。 尽管没有在 SimpleClass 类中定义任何成员,但示例输出表明它实际上有九个成员。 这些成员的其中之一是由 C# 编译器自动为 SimpleClass 类型提供的无参数(或默认)构造函数。 剩余八个是 Object(.NET 类型系统中的所有类和接口最终隐式继承自的类型)的成员。
下面的例子,用来隐式继承的toString()方法
-
- namespace Classes
- {
- public class EmptyClass
- { }
- }
- namespace Classes;
-
- using System.Reflection;
-
- public class SimpleClassExample
- {
- public static void Main()
- {
- EmptyClass sc = new();
- Console.WriteLine(sc.ToString());
- //Classes.EmptyClass
- }
- }
上面例子调用 SimpleClass 从 Object 继承而来的 SimpleClass.ToString 方法。
下表列出了可以在 C# 中创建的各种类型及其隐式继承自的类型。 每个基类型通过继承向隐式派生的类型提供一组不同的成员。