通过案例理解Abstract类和interface类

         IBM上的一篇文章  看了之后深受启发。

        看上面一篇可以理解的就好了,我这里是按照自己的理解,啰嗦的进行一下表述。

 

        如果是偶尔阅读到这里,这个不算,我们假设你是主动搜索相关关键字看到的这里。那么,好,我们就有了一个你使用过多次相关类的经验的前提,你很可能疑惑这个问题:在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,那为什么要有两种呢?

 

        还是要强调一下,假设读者是有使用经验的。

        开始!这是个通过李雷和韩梅梅的爱情故事来理解的例子

        先上包结构


        定义了Man.classWoman.class两个抽象(abstract)类,代码如下:

package abstracts;

public abstract class Man {
	
	public abstract String adamsApple();
	public abstract String beard();
	public abstract String peeStand();
	protected boolean canGiveBirthToAChild(){
		return false;
	}
}

package abstracts;

public abstract class Woman {
	
	public abstract String bigChest();
	public abstract String longHair();
	public abstract String peeSquat();
	protected boolean canGiveBirthToAChild(){
		return true;
	}
}

        然后定义一个Characteristic接口(interface)类:

package interfaces;

public interface Characteristic {
	//外部特征
	void appearance();
	//毛发
	void hair();
	//嘘嘘
	void pee();
}

        接下来主角要出场了,先上韩梅梅:

package someone;

import interfaces.Characteristic;
import abstracts.Woman;

public class HanMeimei extends Woman implements Characteristic{

	//大湿胸
	public String bigChest() {
		// TODO Auto-generated method stub
		return "D cup is my pride";
	}
	//长发
	public String longHair() {
		// TODO Auto-generated method stub
		return "dai wo chang fa ji yao";
	}
	//呵呵
	public String peeSquat() {
		// TODO Auto-generated method stub
		return "hahahaha";
	}

	public void appearance() {
		System.out.println(bigChest());
	}

	public void hair() {
		System.out.println(longHair());
	}

	public void pee() {
		System.out.println(peeSquat());
	}

}

        这里我们直接调用abstract实现方法的值,不要问我为什么,就是想,当然也可以直接打印的。没什么毛病,继续李雷:

package someone;

import interfaces.Characteristic;
import abstracts.Man;

public class LiLei extends Man implements Characteristic{

	/**
	 * 小趣闻:喉结的英语是亚当的苹果,跟圣经里亚当偷吃苹果有关,
	 * 神奇的是卡个苹果居然没噎死
	 */
	public String adamsApple() {
		// TODO Auto-generated method stub
		return "I hava an adam`s apple";
	}
	//胡须
	public String beard() {
		// TODO Auto-generated method stub
		return "I have to fix beard everyday";
	}
	//站着撒尿
	public String peeStand() {
		// TODO Auto-generated method stub
		return "need a little time";
	}
	
	public void appearance() {
		System.out.println(adamsApple());
	}
	public void hair() {
		System.out.println(beard());
	}
	public void pee() {
		System.out.println(peeStand());
	}
}

 

        除了abstract过来的方法名以外,大同小异。

        这个时候,我们到知道如果想打印信息可以通过接口这样测试:


        也可以这样测试:

        到了这里,好像整体来看也没什么异常,好,那我们反过来看:


        就单纯看上面这张图,我们改怎么描述HanMeimei?无非两种:

        1.HanMeimei是个带有特征的女人;

        2.HanMeimei是带有女人的特征?

        感觉来看1是靠谱的,同样的LiLei解释为“有特征的男人”是合适的。

        如果你思维够缜密,你会发现这只是我用语文来强词夺理,如果把两个抽象的类换一下名字,2的说法就成了合理的。换个角度。

        如果再细心点,上面给出代码的类对比开始的结构图中似乎少了LiHua的存在。

        如果LiHua是这样的:


        Lihua是特征?Lihua有特性?似乎都可以,那么再看:


        很显然,LiHua有特征,有爱好这样更说的通一些。但是这个时候,LiHua的本征是什么?我们是不知道的。LiHuaHanMeimei生的(当然LiLei也是很关键的),那我们让LiHua extend HanMeimei好了!也不对啊,从人物设定来讲LiHua不是某个HanMeimei,这个逻辑是不通的。在这里的关系中,需要给Lihua一个本征的定义,就只能是extend Man 或者Woman了。

        为什么要这样呢?因为abstract类只允许继承一个,而interface允许实现多个。这个“单”和“多”的限制,就要求了在进行抽象时,abstract类更倾向本征性质的内容,而interface则侧重功能的引入。

        abstract Class倾向本征,isA的概念;interface倾向于功能,likeA的概念。

        再然后呢?你可以随便选个性别让他/她继承一下。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

公贵买其鹿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值