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、抽象类和接口的相同点和区别

相同点:

  1. 抽象类和接口都不能实例化。
  2. 包含未实现的方法声明
  3. 派生类继承抽象类或者接口的时候,都必须实现抽象类中的抽象方法,或者实现接口的所有成员。

不同点:

  1. 抽象类可以通过间接实例化子类的方式来实例化抽象类,但是接口不能这样。
  2. 抽象类只能单继承,而接口可以多继承(继承多个接口,逗号隔开,但是接口不能继承类)
  3. 接口只能定义抽象规则,抽象类既能定义抽象规则也能提供已实现的成员。
  4. 接口是一组行为规范,抽象类是一个不完全的类,着重于族的概念。
  5. 接口支持回调,抽象类不能实现回调,因为继承不支持。
  6. 接口多定义对象的行为,抽象类多定义对象的属性。

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) { }
    }
}
 
全部评论

相关推荐

不愿透露姓名的神秘牛友
11-20 19:57
已编辑
某大厂 golang工程师 23.0k*16.0, 2k房补,年终大概率能拿到
点赞 评论 收藏
分享
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务