1. 虚方法virtual
l 虚方法可以给父类中的方法一个实现,比如ToString()方法
l 虚方法必须有实现部分,抽象方法没有提供实现部分
虚方法 virtual,虚方法给父类提供了一种默认的实现,
子类可以使用override重写虚方法
虚方法不能出现在密封类(sealed)中
虚方法和抽象方法的区别
虚方法必须有实现,抽象方法必须没有实现
抽象方法必须在抽象类中声明,虚方法可以出现在抽象类中
抽象方法必须在子类中重写,虚方法可以被重写
2.Person.cs(父类)
//虚方法必须有实现
public virtual void SayHi()
{
Console.WriteLine("大家好,我是" +name+"学生");
}
public override string ToString()
{
return name;
}
Teacher.cs(子类),又重写了Person类中的虚方法:
public override void SayHi()
{
Console.WriteLine("大家好,我是"+name+"老师");
}
3.怎么实现多态-接口
l 接口是定义一种能力,规定子类能干什么和抽象类有些相似,解决类的单根继承。接口可以实现多继承
l 案例
• 鸟-麻雀sparrow,鸵鸟ostrich,企鹅penguin,鹦鹉parrot
• 鸟能飞鸵鸟,企鹅不能。。。你怎么办
l 练习:从学生,老师,校长类中抽象出人的类,学生和老师都有收作业的方法,但是校长不会收作业
l 子类继承抽象类,实现接口
l 接口中的成员必须不能有实现
l 接口中的成员不能有访问修饰符,隐式公开
l 接口中可以有属性、方法、索引器等,但不能有字段
l 接口中的所有成员必须被子类中全部实现
定义接口:interface IFlyable
{ //不能有大括号{}
//接口成员不能有访问修饰符,隐式公开
void Fly();
void Test();
}
调用接口:
ISpeakable speak = new Parrot();
speak.Speak();
//调用ISpeakable中的test(IFlyable 中也有Test)
speak.Test();
Parrot p = speak as Parrot;
if(p != null)
p.Fly();
//面试题:接口中能定义什么?
//接口中可以定义方法、属性、索引器。因为属性、索引器本质上也是方法。
//接口中不能定义字段,因为字段是实现。
//一个类只能有一个父类
//一个类可以实现多个接口。接口只能决定能干什么,怎么干由类来实现
面试题
l 1. 如何使用virtual和override?
• Person per = new Student();
• Per.SayHI()调用的子类重写的SayHi方法
l 2. 如何使用abstract和override?
l 3. "重载" 、 "重写"、 "隐藏"是同一个概念吗?
l 4.抽象类和接口的区别
抽象类和接口的区别
接口定义类的公共行为,抽象类定义类的公共实现
- 一个类只能继承自一个类(抽象类),但是可以同时实现多个接口
- 接口中不能有实现,抽象类中可以有未实现成员也可以有实现的成员
- 接口中未实现的方法必须在子类中重写,抽象类中未实现的成员必须在子类中实现
- 好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。
什么时候使用抽象类,什么时候使用接口
抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。
1.飞机会飞,鸟会飞,他们都继承了同一个接口“飞”;但是F22属于飞机抽象类,鸽子属于鸟抽象类。
2. 就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我可以给你个具体的铁门或木门(多态);而且只能是门,你不能说它是窗(单继承);一个门可以有锁(接口)也可以有门铃(多实现)。 门(抽象类)定义了你是什么,接口(锁)规定了你能做什么(一个接口最好只能做一件事,你不能要求锁也能发出声音吧(接口污染))。
static void Main(string[] args)
{
//传递的是实现了接口的对象
Collect(new Student());
//返回的是实现了接口的对象
ICollectHomework icol = Create("student");
icol.Collect();
Console.Read();
}
//接口作为参数
static void Collect(ICollectHomework homework)
{
homework.Collect();
}
//接口作为返回值
static ICollectHomework Create(string type)
{
ICollectHomework icol = null;
switch (type)
{
case "student":
icol = new Student();
break;
case "teacher":
icol = new Teacher();
break;
default:
break;
}
return icol;
}