c#学习笔记-继承

根据 C# 中的继承 | Microsoft Learn

做的笔记,具体请参考https://learn.microsoft.com/zh-cn/dotnet/csharp/fundamentals/tutorials/inheritance 

本文只是对教程中的例子进行实践。 

一.继承

1.1 保护级别

1.1.1 Compiler Error CS0122

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

此错误可以参考上面的链接 

1.1.2 只有在基类中嵌套的派生类中,私有成员才可见。

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

1.2 受保护成员仅在派生类中可见。

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仅允许当前类访问,派生类不能访问

1.2重写继承的成员

 基类成员必须标记有 virtual 关键字,才能重写继承的成员。 默认情况下,基类成员没有 virtual 标记,因此无法被重写。 标记有 abstract 关键字的基类成员要求派生类必须重写它们。继承仅适用于类和接口。

1.3 隐式继承

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 类型系统中的所有类和接口最终隐式继承自的类型)的成员。

1.3.1 隐式继承例子

下面的例子,用来隐式继承的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# 中创建的各种类型及其隐式继承自的类型。 每个基类型通过继承向隐式派生的类型提供一组不同的成员。

类型类别隐式继承自
classObject
structValueTypeObject
enumEnumValueTypeObject
delegateMulticastDelegateDelegateObject

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值