上一个
下一个

抽象类与接口

0.前言

在C++中,一个类可以继承许多类,我们称之为多继承,但是在java中这是不被允许的。也许你看到过一句话:我们可以使用接口来达成多继承。我们暂且将这个问题置于一边,先看看C++中如何实现接口。

 

1.C++中的接口

接口描述了一个类的特征和行为,但是却不需要具体实现,很自然的可以联想到抽象类来实现。试考虑以下代码:

				
					class Geography
{
public:
	Geography():area(0),circum(0){};
	double GetArea(){
		return area;
	}
	void SetArea(double a)
	{
		area=a;
	}
	virtual void CalculateArea()=0;
private:
	double area;
	double circum;
	
};
				
			

我们定义了一个抽象类,数据域中的area是不开放的,我们给了两个函数来对它访问,同时定义了一个虚函数,下面是它的一个实现。

				
					class Circle:public Geography
{
public:
	Circle(double r):Geography(),radius(r)
	{
		CalculateArea();
	};
	void CalculateArea()
	{
		SetArea(radius*radius*3.1416);
	}
private:
	double radius;
};
				
			

在C++中抽象类和接口没有分开,但我们能隐隐感受到两者区别,类有很强的is-a关系,但是接口只是描述了一方面通用的属性。

2.Java中的接口

先看看如何像C++那样子实现我们想要的。

				
					abstract class Animal{
    public abstract String howToEat();
}
class Chicken extends Animal{
    @Override
    public String howToEat() {
        return "Fry it";
    }
}
class Duck extends Animal{
    @Override
    public String howToEat(){
        return "Roast it";
    }
}
public class Main {
    public static void main(String[] args) {
        Animal animal=new Chicken();
        eat(animal);
        animal = new Duck();
        eat(animal);
    }
    public static void eat(Animal a)
    {
        System.out.println(a.howToEat());
    }
}
				
			

但是从设计角度来考虑,难道只有动物是可以吃的吗?我们也会吃蔬菜水果零食等等,而且进一步思考,怎么被吃似乎不是一个动物的方法吧,将它归为所有动物都有的似乎不太合适,下面是接口是如何实现的。

				
					interface Edible{
    public abstract String howToEat();
}
class Chicken implements Edible{
    @Override
    public String howToEat() {
        return "Fry it";
    }
}
class Duck implements Edible{
    @Override
    public String howToEat(){
        return "Roast it";
    }
}
class Watermelon implements Edible{
    @Override
    public String howToEat(){
        return "just eat it";
    }
}

public class Main {
    public static void main(String[] args) {
        Edible food = new Chicken();
        eat(food);
        food = new Watermelon();
        eat(food);
    }
    public static void eat(Edible a)
    {
        System.out.println(a.howToEat());
    }
}
				
			

3.总结

接口为抽象提供了一种更加合理的选择。接口更加像是一种……协议?我们规定了接口就代表这些类需要达成这些才是合格的。

总结一下抽象类和接口的区别,以下内容摘自知乎:

1)语法层面上

  • 接口中不能有 public 和 protected 修饰的方法,抽象类中可以有。
  • 接口中的变量只能是隐式的常量,抽象类中可以有任意类型的变量。
  • 一个类只能继承一个抽象类,但却可以实现多个接口。

2)设计层面上

抽象类是对类的一种抽象,继承抽象类的类和抽象类本身是一种 is-a 的关系。

接口是对类的某种行为的一种抽象,接口和类之间并没有很强的关联关系,所有的类都可以实现 Serializable 接口,从而具有序列化的功能。

订阅评论
提醒
1 评论
最旧
最新 最多投票
内联反馈
查看所有评论

[…] 算一算很长时间没有写过文章了。不过隔壁出了个Java的抽象类与接口,那我当然很有兴趣来写写C#的抽象类和接口啦。本文意在于介绍抽象类以及接口的配合使用,关于更多细节请参考微软官方文档。 […]

《抽象类与接口》

1
0
希望看到您的想法,请您发表评论x