浅谈Java接口(interface)

什么是接口

Java接口(Interface),是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

接口有什么用

接口有什么用,这个问题在初学Java时一度困扰着我,查阅资料时对于接口的太多解释又让像我这样的小白一脸懵逼,一些专业术语不仅不能帮助理解,反而让人望而生畏。
不知道其他人怎么觉得,反正作为一个理工男,尤其作为一个新手的时候,我看到一大串的概念就头疼,我比较喜欢直接看例子

继承和规范的作用:

定义了一个动物接口(interface Animals):

public interface Animals{
	public String voice();//动物的叫声
}

里面只有一个抽象方法voice(),即动物的叫声,只有方法头,没有实现。
接口要求实现它的类必须实现其所有的抽象方法。于是有两个用户定义的类 ,动物有多种,猫和狗是其中的两种,所有我们在它们中分别实现猫叫和狗叫的方法。


一个狗类(class Dog):

public class Dog{
	@Override
	public String voice(){
		return "汪汪";
	}
}

一个猫类:

public class Cat{
	@Override
	public String voice(){
		return "喵喵";
	}

这样就有个问题了,既然接口只有方法头,而这些方法头在实现类中又要写一次,岂不是多次一举。
难道只是为了规范化,即强迫使用这个接口的类必须使用带这些方法头的方法?

当然不只是这样。
实现类实现接口,就像子类继承父类一样,有继承关系
比如在一个测试类中定义一个方法来知道一个动物是怎么叫的:

我要知道猫叫就得这样写:

void foo(Cat c){
	System.out.println(c.voice());
}

我要知道狗叫就得这样写:

void foo(Dog d){
	System.out.println(d.voice());
}

这样,每多一种动物,就得往类中新增一个方法,这样是非常不利于更新和维护的,而且会大大增加代码量。
但是如果把猫狗的行为抽象化,即猫叫狗叫都是动物叫,这样不管方法foo的形参是哪种动物,都能得到他的叫声,代码如下:

void foo(Animal a){
	System.out.println(a.voice());
}

这样,测试类只有一个方法foo,但是我传的参数既可以是Cat对象,也可以是Dog对象,因为实现Animal接口之后的猫类狗类都是Animal类,而且猫狗都会叫(即猫类狗类都“被迫”地实现了voice这个方法)。

行为参数化:

行为参数化是什么?简单说就是把一种行为作为方法的形参。
不理解没关系,看个例子就知道了:

比如,女朋友跟我说想吃红苹果,我就需要一个方法去判断超市的苹果是不是女朋友喜欢的苹果:

void judge(String color){
	if(color.equals("红")) System.out.println("是我要的苹果");
	else System.out.println("不是我要的苹果");
}

但是如果女朋友要求突然提高,说喜欢大的红苹果,那我就需要更改之前的方法,参数需要多一个“大小”:

void judge(String color,String size){
	if(color.equals("红")&&size.equals("大"))
		 System.out.println("是我要的苹果");
	else System.out.println("不是我要的苹果");
}

这样,每当女朋友改变要求的时候,我们都需要改变原来的代码,这通常是不被允许的,因为它破坏了代码原有的结构。
也许我们可以把苹果封装成类,这样参数就只要传入苹果的对象就行了。不过即使这样if里面的判断条件还是会改变,这个时候接口(interface)派上用场了。

我们定义一个接口GF (girlfriend缩写):

public interface GF{
	public boolean islike();
}

原来的判断方法改成:

void judge(GF gf){
	if(gf.islike())
		 System.out.println("是我要的苹果");
	else System.out.println("不是我要的苹果");
}

这样女朋友给定需求的时候,我们只需要在主程序新建一个匿名类进行传参就可以了,而原方法体不许做任何改变。

//创建匿名类
GF g=new GF(){
	@Override
	public boolean islike(){
		return color.equals("红") && size.equals("大");
	}
}
//调用judge函数
judge(g);

这里创建匿名类的原因是:不必为一个临时使用的类去创建一个专门的文件。
对于函数式接口(只有一个抽象方法的的接口),如果知道什么是lambda表达式的话,写起来更简单。

看完这个例子再理解行为参数化就容易了,这里就是把“判断女朋友喜欢的苹果”作为一种行为,并将这种行为作为参数传到judge函数。

以上就是接口的两种常用方法,也是作为小白经常能碰到的一些使用例子,这里也是我自己开始去理解接口时的心得。
关于更多接口的更详细,更专业的解释网上也有很多大佬发表过言论,这里我就不在这班门弄斧啦(哈哈)!
如果本文有什么说的不对的地方,也请路过的大佬帮忙指出。

发布了18 篇原创文章 · 获赞 16 · 访问量 1420

猜你喜欢

转载自blog.csdn.net/weixin_44155115/article/details/103764457