在现实世界与抽象空间游走的一週
匆匆忙忙行军式的步伐迈向抽象类别的世界,老实说真的有点挫折,跟不太上同学们的脚步,对于我这张程式白纸来说果然不是件容易的事!不过我相信每天重複做的事还是会进步的!我知道我有在前进,但我得更努力才能追上同学们的脚步了><
应该算是一个好消息(? 我终于被距离给打败了,在每日睡眠不足的情况下通勤两小时左右的时间实在太舟车劳顿了!
所以我决定寻找一个新的落脚处
继承
首先理解的是继承就是修改与扩充一个类别的内容,将一些共有的属性和方法定义在这个类中,当某一个类需要使用到这些方法和属性的时候,就可以通过extends关键字直接调用父类别中的成员变量和方法,增加程式的便利性。
举例来说:
有一个Animal的类别
属性:体重,名字,年龄方法:移动
再定义一个Cat的类别
属性:体重,名字,年龄,毛色方法:移动,吃,睡
其中很多东西都跟动物重複。
在现实中,猫是一种动物,应该拥有动物的属性及方法,然后再加上猫专属的属性和方法(扩充)。
我们可以把动物当成父类别,狗『继承』动物,猫是『子类别』。
子类别会拥有父类别的所有属性,方法,再加上自己定义的属性及方法,所以可以说子类别是父类别的延伸(extend)。
super();
父类别的建构子 super(.)一定要写在第一行!
利用super(.)可以呼叫父类别中定义好相应参数的建构子,很多时候父类别已经定义好的东西,子类别可直接调用,设计上比较好维护,设计逻辑比较有阶层性。
覆写(override)
如果父类别没有方法,子类别新增一个方法,叫做扩充。有方法,则子类别去覆写,叫修改,也就是@override。
Java有规範,父子类别都有的情况下,优先使用子类别。
Override & Overloading 比较
覆写(Override):当父子类别有同署名 ( 同名同参数 ) 的方法,子类别会去覆盖掉父类别的方法。
多载(Overloading):不论在相同类别还是父子类别,有同名不同参数的方法,则会同时存在。
回传值的限制
子类别在 @Override 方法的时候,回传值必须是父类别**“原本回传值的类别” 或是 “原本回传值的子类别”**。
因此,如果是回传基本资料型态,基本资料型态没有继承关係,所以不能更改成回传其他基本资料型态。
多型
假设有三个子类别都继承自某父类别,则可以宣告一个父类别的变数是子类别的实体,这就是最基础的多型。
举例来说可以说Square就是Shape-->Shape shape=new Square();
//宣告Shape变数放入Square实体,Square一定包含Shape所有内容
抽象类别
当定义类别时,可以仅宣告方法名称而不实作,这样的方法称之为「抽象方法」(Abstract method),如果一个类别中包含了抽象方法,则该类别称之为「抽象类别」(Abstract class),抽象类别是个未定义完全的类别,所以它不能被用来生成物件,它只能被扩充并于扩充后完成未完成的抽象方法定义。
(抽象类别有建构子,但不能被创建出实体,抽象类别在概念上就是抽象的,不应该有实体。)
抽象方法
1.抽象方法将实现方法的时间点延后,交给子类别去实现。
2.如果子类别不是抽象类别,里面就不能包含抽象方法。
3.当子类别继承抽象类别就会@override把抽象方法实现(但子类别也可以是抽象类别,延后方法实现的时间)
4.抽象方法一定要存在抽象类别中
介面(Interface)
介面就是只能有抽象方法的类别,介面中的所有东西都是未实现的。(须注意:介面中不能有任何属性和已经实现的方法)介面中只能定义方法原型,不能有方法实体。介面可以和extends并存,继承自一个类,实现多个介面,但不能继承多个类。类别实现了介面后,就会有介面里面的方法。补充:介面就是取出共同的部分,和父类别的概念是一样的,但作为类别的延伸, 补充了多重继承的特性。因为子类别只能继承自一个父类别,拓展有限,但若选择实现多个介面,子类别的实例就可作为多种不同型态的变数存取。
抽象类别与介面的比较 Abstract Classes Compared to Interfaces
抽象类别与介面有点像,两个都不行被实体化成物件。
抽象类别
1.用于被继承,类别要实作定义的抽象方法。
2.抽象类别中可以定义完整的方法(方法本体),可以只定义方法原型。
3.可以定义完整的资料栏位供继承类别使用。
4.设计中心以资料为主体。
介面
1.用于被实作,类别要实作定义的方法。
2.介面中只能定义方法原型,能有方法本体。
3.方法的修饰子必为public abstract。
4.设计中心以行为为主体。
5.一般来说有共同的概念可以继承相同的抽象父类别,
若只是行为相同,以介面设计比较恰当。