复习:J&C:面向对象:继承(构造函数调用 & 禁止) / 现代接口
sealed class Student : Person {}此外,静态类不能被继承。
public OnlineStudent() : base("atai") {
复习:is(Java中的instanceof)
C#中还利用直接使用as进行转换。如果转换不成功,会返回null值。
Student wx = new OnlineStudent { City = "西安" }; OnlineStudent owx = wx as OnlineStudent; if (owx == null) //转换没成功
as在底层实际上是也利用了is,但飞哥个人认为as的写法更“舒服”一点。同学们可以依据自己的喜好选择使用is或as。
关于多态,之前我们学习的是C#中可以使用virtual关键字定义虚方法,然后在子类中override:这样,调用方法的依据是对象而不是变量类型。
但是,#试一试#没有virtual和override,会得到一个警告,大意是:
子类Student的Eat()方法会隐藏(hide)父类Person的Eat()方法。如果这是我们有意而为之的(intented),让我们添加new关键字。
所以,规范的写法应该是:
public class Student { internal void Eat() class OnlineStudent : Student { internal new void Eat() //注意关键字new
这样的话,变量调用的方法就不再根据对象而是根据变量类型了:
//OnlineStudent wx = new OnlineStudent(); Student wx = new OnlineStudent(); wx.Eat(); //哪一个Eat()方法?
new还可以作用于静态方法。
之前我们学习的,在C#中都被称为接口的隐式实现。
但假如一个子类实现了多个接口,且多个接口中定义了相同方法的时候,按隐式实现如何区分呢?C#中引入了接口的显式实现。
比如我们两个接口,都定义了Practise()方法:
internal interface IPlay { void Practise(); } internal interface ILearn { void Practise(); }
现在就不能在Student中隐式实现Practise()了,因为子类中只能声明一个Practise()方法啊!
所以我们需要进行区分:
void IPlay.Practise() //不能有访问修饰符 { Console.WriteLine("玩"); } void ILearn.Practise() //接口名前缀 { Console.WriteLine("学习"); }
这样就OK了,但是还要注意一点,显式实现的接口方法,不能用子类类型的变量进行调用,而是:
IPlay atai = new Student(); atai.Practise(); ILearn xj = new Student(); xj.Practise();
引入了extension method,其特点为:
我们也可以自定义自己的扩展方法:
namespace MyNamespace { public static class TeacherExtesion /*毫无意义的XXXX也行,^_^*/ { public static void Greet(this Teacher teacher, string words) { //teacher参数是可以作为正常参数使用的 Console.WriteLine($"我是{teacher.Name},{words}"); } //方法重载 public static void Greet(this Teacher teacher) { } } }
其他见:J&C:面向对象:继承(构造函数调用 & 禁止) / 现代接口(可利用显式接口,实现完成第7题)
多快好省!前端后端,线上线下,名师精讲
更多了解 加: