C#接口和抽象类的区别
1.前言
对于接口和抽象类概念中非常混淆,今天就来总结一下两者之间的区别。
2.接口
接口是一种定义的规范,在实际开发中,编码者会规定这种规范,下一任编码者必须按照定义好的规范去实现具体的业务,如果没有定义接口规范,那开发不是乱套了吗。接口可以包含方法、属性、索引器和事件作为成员。
接口存在的意义是为了实现多态;
接口中只能包含方法(属性、事件、索引);
接口的成员不能有任何实现;
接口不能被实例化;静态类、抽象类不能直接被实例化
接口的成员不能有访问修饰符(默认为public);
实现接口的子类必须将接口的所有成员函数实现;
子类实现接口的方法时,不需要任何关键字,直接实现即可。(抽象类、虚方法需要加override)
注意:虽然抽象类不能直接的进行实例化(new),但是可以间接通过对子类的实例化间接可以实例化父类,也就是通过父类的应用来指向子类的实例间接地实现父类的实例化,因为子类在实例化之前,一定会先实例化它的父类。这样创建了继承抽象类的子类对象,也就把其父类(抽象类)给实例化了。
应用理解如下:(首先,定义一个抽象类B,包含抽象方法play())
public abstract class B {
private String str;
public B(String a){
System.out.println("父类已经实例化");
this.str = a;
System.out.println(str);
}
public abstract void play();
}
然后,定义一个子类C去继承类B,并实现其中的抽象方法:
public class C extends B{
public C(String c){
super(c);
System.out.println("子类已经被实例化");
}
@Override
public void play() {
System.out.println("我实现了父类的方法");
}
public static void main(String[] args){
B c = new C("c");
}
}
运行结果如下:
父类已经实例化
c
子类已经被实例化
3.抽象类
抽象类,在面向对象过程中,所有的对象都是类描绘的,反过来,类里面的数据不足以把具体的对象描绘出来,这样的类就是抽象类。
抽象方法只能出现在抽象类中,但是抽象类中可以包含普通方法。普通类中只能包含普通方法
在父类中定义的抽象方法不能实现。普通方法可以实现
抽象类不能实例化(也就是不能new出来)。
抽象类与抽象方法需要添加abstract关键字。
子类实现父类的抽象方法时,需要添加override关键字。
如果抽象类的子类不是抽象类,那么子类中必须重写父类抽象类的所有抽象方法。
抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类(普通类)必须覆盖它们。
4、抽象类和接口的相同点和区别
相同点:
- 抽象类和接口都不能实例化。
- 包含未实现的方法声明
- 派生类继承抽象类或者接口的时候,都必须实现抽象类中的抽象方法,或者实现接口的所有成员。
不同点:
- 抽象类可以通过间接实例化子类的方式来实例化抽象类,但是接口不能这样。
- 抽象类只能单继承,而接口可以多继承(继承多个接口,逗号隔开,但是接口不能继承类)
- 接口只能定义抽象规则,抽象类既能定义抽象规则也能提供已实现的成员。
- 接口是一组行为规范,抽象类是一个不完全的类,着重于族的概念。
- 接口支持回调,抽象类不能实现回调,因为继承不支持。
- 接口多定义对象的行为,抽象类多定义对象的属性。
5.代码分析
接口实例
using System;
//接口的定义
interface ICreature
{
void Eat();
void Walk(int distance);
string Vocalize();
}
public class Author : ICreature
{
private string name;
public Author(string name)
{
this.name = name;
}
public void Eat() { }
public void Walk(int distanc) { }
public string Vocalize()
{
return "";
}
}
class Program
{
static void Main(string[] args)
{
ICreature man = new Author("marcopro");
man.Eat();
man.Walk(10);
man.Vocalize();
}
}
抽象类实例
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Author ar = new Author("Tom");
Reader rdr = new Reader("Jack");
Console.WriteLine(ar.name);
Console.WriteLine(rdr.name);
ar.doSomething();
rdr.doSomething();
}
}
public abstract class Human
{
public string name;
public int age;
public Human(string name)
{
this.name = name;
this.age = 0;
}
public void showBaseInfo(){ }
public void showFullInfo(){ }
public void doSomething() {
Console.WriteLine(this.name+": let me do something!");
}
}
public class Author:Human
{
public Author(string name) : base(name) { }
}
public class Reader : Human
{
public Reader(string name) : base(name) { }
}
}