俄罗斯方块与抽象类的故事

1. 什么是抽象类

总是在想为何要引用抽象类,通常类不就够用了吗。通常类里定义的方法,子类也能够覆盖,不必定义成抽象的啊。数组

先明确一点,抽象类和抽象方法的概念:spa

☆☆☆设计

抽象方法:在类中没有方法体的方法,就是抽象方法。对象

抽象类:含有抽象方法的类就叫抽象类。继承

抽象类中的抽象方法必须被实现!游戏

☆☆☆引用

个人理解为:抽象类天生设计出来就是被继承的,笼统的表示一些实体不必实例化,其中方法的方法体没有意义天然也就没有方法体。方法

其实不是说抽象类有什么用,通常类确实也能知足应用,可是现实中确实有些父类中的方法确实没有必要写,由于各个子类中的这个方法确定会有不一样,因此没有必要再父类里写。固然你也能够把抽象类都写成非抽象类,可是这样没有必要。地图

而写成抽象类,这样别人看到你的代码,或你看到别人的代码,你就会注意抽象方法,而知道这个方法是在子类中实现的,因此,有个提示做用。移动

2. 理解与剖析

问你个问题,你知道什么是“东西”吗?什么是“物体”吗?
“麻烦你,小王。帮我把那个东西拿过来好吗”
在生活中,你确定用过这个词--东西。
小王:“你要让我帮你拿那个水杯吗?”
你要的是水杯类的对象。而东西是水杯的父类。一般东西类没有实例对象,但咱们有时须要东西的引用指向它的子类实例。

你看你的房间乱成什么样子了,之后不要把东西乱放了,知道么?
又是东西,它是一个数组。而数组中的元素都是其子类的实例。
---------
上面讲的只是子类和父类。而没有说明抽象类的做用。抽象类是据有一个或多个抽象方法的类,必须声明为抽象类。抽象类的特色是,不能建立实例。

这些该死的抽象类,也不知道它有什么屁用。我非要把它改一改不可。把抽象类中的抽象方法都改成空实现。也就是给抽象方法加上一个方法体,不过这个方法体是空的。这回抽象类就没有抽象方法了。它就能够不在抽象了。

当你这么尝试以后,你发现,原来的代码没有任何变化。你们都仍是和原来同样,工做的很好。你这回可能更加相信,抽象类根本就没有什么用。但老是不死心,它应该有点用吧,否则创造Java的这伙传说中的天才不成了傻子了吗?

接下来,咱们来写一个小游戏。俄罗斯方块!咱们来分析一下它须要什么类?
我知道它要在一个矩形的房子里完成。这个房子的上面出现一个方块,慢慢的下落,当它接触到地面或是其它方块的尸体时,它就中止下落了。而后房子的上面又会出现一个新的方块,与前一个方块同样,也会慢慢的下落。在它尚未死亡以前,我能够尽可能的移动和翻转它。这样可使它起到落地时起到必定的做用,若是好的话,还能够减下少几行呢。这看起来好象人生同样,它在为后来人努力着。
固然,咱们不是真的要写一个游戏。因此咱们简化它。我抽象出两个必须的类,一个是那个房间,或者就它地图也行。另外一个是方块。我发现方块有不少种,数一下,共6种。它们都是四个小矩形构成的。可是它们还有不少不一样,例如:它们的翻转方法不一样。先把这个问题放到一边去,咱们回到房子这个类中。

房子上面老是有方块落下来,房子应该有个属性是方块。当一个方块死掉后,再建立一个方块,让它出如今房子的上面。当玩家要翻转方法时,它翻转的究竟是哪一个方块呢?固然,房子中只有一个方块能够被翻转,就是当前方块。它是房子的一个属性。那这个属性究竟是什么类型的呢?方块有不少不一样啊,一共有6种之多,我须要写六个类。一个属性不可能有六种类型吧。固然一个属性只能有一种类型。

咱们写一个方块类,用它来派生出6个子类。而房子类的当前方块属性的类型是方块类型。它能够指向任何子类。可是,当我调用当前方块的翻转方法时,它的子类都有吗?若是你把翻转方法写到方块类中,它的子类天然也就有了。能够这六种子类的翻转方法是不一样的。咱们知道'田'方块,它只有一种状态,不管你怎么翻转它。而长条的方块有两种状态。一种是‘-’,另外一种是‘|’。这可怎么办呢?咱们知道Java的多态性,你可让子类来重写父类的方法。也就是说,在父类中定义这个方法,子类在重写这个方法。

那么在父类的这个翻转方法中,我写一些什么代码呢?让它有几种状态呢?由于咱们不可能实例化一个方块类的实例,因此它的翻转方法中的代码并不重要。而子类必须去重写它。那么你能够在父类的翻转方法中不写任何代码,也就是空方法。

咱们发现,方法类不可能有实例,它的翻转方法的内容能够是任何的代码。而子类必须重写父类的翻转方法。这时,你能够把方块类写成抽象类,而它的抽象方法就是翻转方法。固然,你也能够把方块类写为非抽象的,也能够在方块类的翻转方法中写上几千行的代码。但这样好吗?难道你是微软派来的,非要说Java中的不少东西都是没有用的吗?

当我看到方块类是抽象的,我会很关心它的抽象方法。我知道它的子类必定会重写它,并且,我会去找到抽象类的引用。它必定会有多态性的体现。

可是,若是你没有这样作,我会认为可能会在某个地方,你会实例化一个方块类的实例,但我找了全部的地方都没有找到。最后我会大骂你一句,你是来欺骗个人吗,你这个白痴。

把那些和“东西”差很少的类写成抽象的。而水杯同样的类就能够不是抽象的了。固然水杯也有几千块钱一个的和几块钱一个的。水杯也有子类,例如,我用的水杯都很高档,大多都是一次性的纸水杯。

记住一点,面向对象不是来自于Java,面向对象就在你的生活中。而Java的面向对象是方便你解决复杂的问题。这不是说面向对象很简单,虽然面向对象很复杂,但Java知道,你很了解面向对象,由于它就在你身边。

相关文章
相关标签/搜索