C#知识:抽象类、抽象方法、接口
在开发过程中接口一般用得较多,程序框架往往定义一堆接口规范,然后程序员自己写逻辑来实现接口功能。掌握接口的知识还是很有必要的。
1、抽象类
- 用abstract关键字修饰的类
- 不能用来实例化对象
- 可以包含抽象方法及普通方法,声明抽象方法时要加上abstract关键字
- 继承抽象类必须重写其所有抽象方法
- 抽象类变量容器可以装载子类对象
- 抽象类主要是用来定义类规则的,子类来定义具体实现
//动物就适合定义为抽象类,因为世界上并不存在名字叫动物的生物abstract class Animal{public string name;public Animal() { this.name = ""; }public Animal(string name) => this.name = name;public abstract void Eat();}
2、抽象方法
- 用abstract修饰的方法
- 只能在抽象类中声明
- 在抽象类中声明的抽象方法没有方法体语句块
- 不能是private,可以是protected
- 继承抽象类的子类必须重写父类的抽象方法,加上override关键字
public abstract void Eat();
3、virtual方法 VS abstract方法
- 两者都可以被子类无限重写
- virtual方法可以有方法体,但abstract方法没有
- 子类可以不重写父类的virtual方法,但必须重写父类的abstract方法
4、接口
- 用interface关键字,与类声明类似
- 接口本质是一组行为的规范
- 接口不能实例化对象,但是可以用接口容器变量装载子类对象
interface IMove2{void Move();}
-
可以继承多个接口
-
接口中不能包含成员变量
-
接口只包含方法、属性、索引器、事件,子类必须实现接口中所有成员
-
接口中的成员没有实现,具体实现由实现接口的类来完成
-
接口可以继承接口
-
接口中成员可以不加访问修饰符,只能是public的*
-
类继承接口后,必须实现接口中所有成员,且访问权限为public
-
接口继承接口本质是行为规范的合并,不用实现接口中的方法
-
实现接口的方法,可以加上virtual关键字在子类中重写
-
接口命名规范一般是IXxx
-
接口中的方法可以重载,子类必须实现所有重载方法
interface IMove{float Speed{get;set;}float this[int idx] { get;set;}void Move();void Move(float speed);Action MyEvent();}
5、显式实现接口
- 若同时继承多个接口,接口中有同名方法,则需要显式实现接口
- 显式实现接口不能写访问修饰符
- 语法为:接口名.方法名
class BadPlane : IMove, IMove2{void IMove.Move(){Console.WriteLine("一号龟速飞行");}void IMove2.Move(){Console.WriteLine("2号龟速飞行");}}
IMove badPlane = new BadPlane();IMove2 badPlane2 = new BadPlane();badPlane.Move(); //一号龟速飞行badPlane2.Move(); //2号龟速飞行
6、接口VS抽象类
- 可以实现多个接口、但只能继承一个抽象类
- 接口中的方法都是抽象方法,抽象类可以包含抽象方法和普通方法
- 接口中的方法默认访问权限为public,而抽象类中的方法必须加上访问修饰符
- 接口不能有成员变量、构造函数,而抽象类可以有
- 重写抽象方法要加override关键字,而实现接口方法不用
- 优先组合而非继承,尽量用接口定义行为,避免复杂的类继承
7、完整代码示例:
namespace LearnAbstractAndinterface
{//飞机和人有移动方法,但是飞机和人之间没有继承关系,这里就可以用接口interface IMove{float Speed{get;set;}float this[int idx] { get;set;}void Move();void Move(float speed);Action MyEvent();}interface IMove2{void Move();}//动物就适合定义为抽象类,因为世界上并不存在名字叫动物的生物abstract class Animal{public string name;public Animal() { this.name = ""; }public Animal(string name) => this.name = name;public abstract void Eat();}class Person : Animal, IMove{public float Speed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public float this[int idx] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public Person() => this.name = "张飞";public Person(string name):base(name) { }public void Move(){Console.WriteLine("步行");}public override void Eat(){Console.WriteLine("吃隆江猪脚饭");}public void Move(float speed){throw new NotImplementedException();}public Action MyEvent(){throw new NotImplementedException();}}class Rabbit : Animal, IMove{public float Speed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public float this[int idx] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public Rabbit() => this.name = "流氓兔";public Rabbit(string name) : base(name) { }public void Move(){Console.WriteLine("跳");}public override void Eat(){Console.WriteLine("吃胡萝北");}public void Move(float speed){throw new NotImplementedException();}public Action MyEvent(){throw new NotImplementedException();}}class Plane : IMove{public float this[int idx] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public float Speed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public virtual void Move(){Console.WriteLine("飞行");}public void Move(float speed){throw new NotImplementedException();}public Action MyEvent(){throw new NotImplementedException();}}class GoodPlane: Plane,IMove2{public override void Move(){Console.WriteLine("一号光速飞行,免费");}void IMove2.Move(){Console.WriteLine("2号光速飞行,免费");}}class BadPlane : IMove, IMove2{public float this[int idx] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public float Speed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }void IMove.Move(){Console.WriteLine("一号龟速飞行");}void IMove2.Move(){Console.WriteLine("2号龟速飞行");}public void Move(float speed){throw new NotImplementedException();}public Action MyEvent(){throw new NotImplementedException();}}internal class Program{static void Main(string[] args){Animal person = new Person();Animal rabbit = new Rabbit();person.Eat(); //吃隆江猪脚饭rabbit.Eat(); //吃胡萝北IMove person2 = new Person(); IMove rabbit2 = new Rabbit();IMove plane = new Plane();IMove goodPlane = new GoodPlane();person2.Move(); //步行rabbit2.Move(); //跳plane.Move(); //飞行goodPlane.Move(); //一号光速飞行,免费IMove2 goodPlane2 = new GoodPlane();IMove badPlane = new BadPlane();IMove2 badPlane2 = new BadPlane();goodPlane2.Move(); //2号光速飞行,免费badPlane.Move(); //一号龟速飞行badPlane2.Move(); //2号龟速飞行}}
}
8、参考资料
- 《唐老狮C#》
本篇结束,感谢您的阅阅阅阅阅阅读~