多态和继承(继承)

时间:2021-12-07 07:49:18

第一天的内容主要是不同情形下的方法重载。这一部分则主要讲面向对象中继承的概念。首先用一个要点图形来定义继承。

继承

一个简单的例子:

ClassA: class ClassA:ClassB { public void Display1() { Console.WriteLine("ClassA Display1"); base.Display1(); } } ClassB: class ClassB { public int x = 100; public void Display1() { Console.WriteLine("ClassB Display1"); } public void Display2() { Console.WriteLine("ClassB Display2"); } } class Program { static void Main(string[] args) { ClassA a = new ClassA(); a.Display1(); Console.ReadKey(); } } /* 输出结果: ClassA Display1 ClassB Display1 */

在如上的例子中,ClassB是父类,ClassA是子类,ClassA继承自ClassB(或ClassB派生出ClassA)。

这个例子也会得到一个警告:“ClassA.Display1()”隐藏继承的成员“ClassB.Display1()”。如果是有意隐藏,请使用关键字 new。  意思是说ClassA中的成员和ClassB中的成员一样,这样基类的就被隐藏了。如果故意为之,,可以用"public new void Display1()"来代替。

知识点:我们可以在子类中定义和基类名称相同的成员,并且子类中的方法总是优先执行然后才是基类(遇到同名的情况时)。当然也可以用base关键字,在子类中调用基类中的成员。另外,继承不能向后兼容(意思就是说基类的实例无法调用派生类的成员,这很好理解)。除了构造函数和析构函数,我们可以从基类继承任何成员。

对于类的成员,有两种类型:

静态成员:类内带有static关键字,他属于这个类,可以直接访问

普通成员:通过这个类的实例来访问,他仅仅属于这个类创建的那个实例

public class ClassB { } public class ClassA : ClassB { } //编译时其实是: public class ClassB:object { } public class ClassA : ClassB { }

在C#中,如果一个类没有继承任何类,那么它也会默认继承自object类,它是所有类的共同的基类。另外一些特殊的类如:System.ValueType、System.Delegate等无法继承。

再看一个例子:

public class ClassW { } public class ClassX { } public class ClassY : ClassW, ClassX { }

这样定义ClasssY时,会报错。知识点:在C#,一个类只能继承自一个类,不支持多继承。(其实C#的多继承可以通过接口来完成)

再看一个例子:

public class ClassW:ClassY { } public class ClassX:ClassW { } public class ClassY : ClassX { }

这样也会报错:涉及“ClassY”和“ClassW”的循环基类依赖项....(3个错误)

知识点:C#中不允许循环相依(Circular dependency)。也就是互相继承

再看一个例子:

public class ClassB { public int b = 100; } public class ClassA:ClassB { public int a = 100; } /// <summary> /// Program: used to execute the method. /// Contains Main method. /// </summary> public class Program { private static void Main(string[] args) { ClassB classB = new ClassB(); ClassA classA = new ClassA(); classA = classB; classB = classA; } }

这个例子会出现错误:无法将类型“ConsoleApplication3.ClassB”隐式转换为“ConsoleApplication3.ClassA”。存在一个显式转换(是否缺少强制转换?)   

知识点:我们可以把一个派生类对象赋值给基类,但反过来不行。既(基类对象=派生类对象,可以;派生类对象=基类对象,不行)

总结:本文主要讲了继承的基本概念。

我们可以在派生类中声明已经在基类中声明的同名函数。

派生类对象调用方法时,基类总是优先执行。

保留的关键字“base”可以派生用于调用基类方法

继承向后兼容。

除了构造函数析构函数,一个类可以基类继承一切

C# 继承自定义不能派生特殊 C# 之类命令 System.Enum System.Delegate System.Array