类继承
通过继承我们可以定义一个新类,新类纳入一个已经声明的类并进行扩展
继承是面向对象的编程的一种基本特性。 借助继承,能够定义可重用(继承)、扩展或修改父类行为的子类。
成员被继承的类称为基类。
继承基类成员的类称为派生类。
C# 和 .NET 只支持单一继承。 也就是说,类只能继承自一个类。
不过,继承是可传递的。
这样一来,就可以为一组类型定义继承层次结构。
换言之,类型 D
可继承自类型 C
,其中类型 C
继承自类型 B
,类型 B
又继承自基类类型 A
。
由于继承是可传递的,因此类型 D
继承了类型 A
的成员。
并非所有基类成员都可供派生类继承。 以下成员无法继承:
虽然基类的其他所有成员都可供派生类继承,但这些成员是否可见取决于它们的可访问性
保护级别
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; } }
受保护成员仅在派生类中可见
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 class A { public void Method1() { // Method implementation. } } public class B : A { } public class Example { public static void Main() { B b = new (); b.Method1(); } }
- Public 访问不受到限制
- Protected 允许本类以及派生类进行访问
- Internal 访问仅限于当前程序集
- Protected Internal 允许本类或派生类访问,注意比Internal的范围广
- Private 仅允许当前类访问,派生类不能访问
隐式继承
.NET 类型系统中的所有类型除了可以通过单一继承进行继承之外,还可以隐式继承自 Object 或其派生的类型。 Object 的常用功能可用于任何类型。
为了说明隐式继承的具体含义,让我们来定义一个新类 SimpleClass
,这只是一个空类定义:
然后可以使用反射(便于检查类型的元数据,从而获取此类型的相关信息),获取 SimpleClass
类型的成员列表。 尽管没有在 SimpleClass
类中定义任何成员,但示例输出表明它实际上有九个成员。 这些成员的其中之一是由 C# 编译器自动为 SimpleClass
类型提供的无参数(或默认)构造函数。 剩余八个是 Object(.NET 类型系统中的所有类和接口最终隐式继承自的类型)的成员。
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: "); //SimpleClass有九个成员: 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 } } }
由于是隐式继承,因此可以调用 SimpleClass
对象中任何继承的成员,就像它实际上是 SimpleClass
类中定义的成员一样。
抽象类
abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用 abstract 修饰符以指示类只能是其他类的基类。
抽象类特性:
-
抽象类不能实例化。
-
抽象类可以包含抽象方法和抽象访问器。
-
不能用 sealed 修饰符修改抽象类,这意味着该类不能被继承。
-
从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。
在方法或属性声明中使用 abstract 修饰符以指示此方法或属性不包含实现。
抽象方法特性:
-
抽象方法是隐式的 virtual 方法。
-
只允许在抽象类中使用抽象方法声明。
-
因为抽象方法声明不提供实实现,所以没有方法体;方法声明只是以一个分号结束,
抽象方法在签名后没有大括号 ({ })
例如:
-
public abstract void MyMethod();
-
实现由 overriding 方法提供,它是非抽象类的成员。
-
在抽象方法声明中使用 static 或 virtual 修饰符是错误的。
除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。
-
在静态属性上使用 abstract 修饰符是错误的。
-
在派生类中,通过包括使用 override 修饰符的属性声明可以重写抽象的继承属性。
抽象类必须为所有接口成员提供实现。
例子:
抽象基类
using System; using System.Collections.Generic; using System.Text; namespace _09_抽象类 { public abstract class Enemy { private int hp; private int speed; public void Move() { Console.WriteLine("Move"); } public abstract void Attack(); } }
子类继承需要实现其抽象方法
using System; using System.Collections.Generic; using System.Text; namespace _09_抽象类 { public class Boss : Enemy { public override void Attack() { Console.WriteLine("Boss进行攻击"); } } }
标签:c#,Object,System,class,继承,-------------,抽象类,public From: https://www.cnblogs.com/misakayoucn/p/17612504.html