當(dāng)前位置:首頁(yè) > 學(xué)習(xí)資源 > 講師博文 > java抽象類(lèi)的作用
本文主要講解了java中抽象類(lèi)與接口的概念、使用及它們之間的區(qū)別。這部分知識(shí)是屬于java語(yǔ)言中核心的知識(shí),是我們理解面向?qū)ο笏枷爰按a設(shè)計(jì)必要掌握的內(nèi)容。
2 抽象類(lèi)
2.1 概念及案例
假設(shè)有一個(gè)Employee和Student類(lèi),考慮一下對(duì)這兩個(gè)類(lèi)的擴(kuò)展。比如每個(gè)員工或者學(xué)生都有姓名,因此可以將name放在較高層次的超類(lèi)Person中。另外可以在Person中再添加一個(gè)方法getDescription,它可以返回對(duì)一個(gè)人的描述。因?yàn)椴恢肋@個(gè)人是學(xué)生還是員工,所以該方法是抽象(abstract)的,也就是沒(méi)有方法體的。
如下代碼:
public abstract class Person {
private String name;
public Person(String name){
this.name = name;
}
public String getName() {
return name;
}
public abstract void getDescription();
}
抽象類(lèi)要使用關(guān)鍵字:abstract
抽象類(lèi)中除了可以包含抽象方法外,也可以包含具體數(shù)據(jù)和具體方法。抽象方法充當(dāng)一個(gè)占位的角色。
擴(kuò)展抽象類(lèi)可以有兩種選擇:
Ø 一種是在子類(lèi)中定義部分抽象方法或不定義抽象方法,這樣就必須將子類(lèi)也標(biāo)記為抽象類(lèi);
Ø 另一種是定義全部的抽象方法,這樣子類(lèi)就不是抽象的了。
類(lèi)即使不含抽象方法,也可以將類(lèi)聲明為抽象的,不過(guò)這樣沒(méi)有什么意義。
抽象類(lèi)不能被實(shí)例化。也就是說(shuō),將一個(gè)類(lèi)聲明為abstract,就不能創(chuàng)建這個(gè)類(lèi)的對(duì)象了,但是可以創(chuàng)建一個(gè)具體子類(lèi)的對(duì)象。需要注意的是,可以定義一個(gè)抽象類(lèi)的對(duì)象變量,但是它只能引用非抽象子類(lèi)的對(duì)象:Person p = new Student();//這里p是一個(gè)抽象類(lèi)Person的變量,但他引用非抽象子類(lèi)Student的實(shí)例。
public class Student extends Person{
public Student(String name) {
super(name);
}
@Override
public void getDescription() {
System.out.println("我是一個(gè)學(xué)生!");
}
}
3 接口
3.1 概述
接口(interface)技術(shù),主要是用來(lái)描述類(lèi)具有什么功能,而并不給出每個(gè)功能的具體實(shí)現(xiàn)。一個(gè)類(lèi)可以實(shí)現(xiàn)(implement)一個(gè)或多個(gè)接口。
在java語(yǔ)言中,接口不是類(lèi),而是對(duì)一組需求的描述,實(shí)現(xiàn)接口的類(lèi)要遵從接口描述的統(tǒng)一格式進(jìn)行定義。
3.2 案例
Arrays類(lèi)中的sort方法可以對(duì)對(duì)象數(shù)組進(jìn)行排序,但前提是:對(duì)象所屬的類(lèi)必須實(shí)現(xiàn)了Comparable接口。
下面是Comparable接口的代碼:
public interface Comparable
public int compareTo(T o);
}
任何實(shí)現(xiàn)Comparable接口的類(lèi)都需要包含compareTo方法,并且這個(gè)方法的參數(shù)是一個(gè)泛型類(lèi)型。
返回一個(gè)整數(shù)值。
說(shuō)明:在調(diào)用x.compareTo(y)的時(shí)候,當(dāng)x小于y時(shí),返回一個(gè)負(fù)數(shù);當(dāng)x等于y時(shí),返回0;當(dāng)x大于y時(shí),返回一個(gè)正數(shù)。
接口中的所有方法自動(dòng)地屬于public。因此,在接口中聲明方法時(shí),也可以不必提供關(guān)鍵字public.
Comparable接口只有一個(gè)方法,有些接口是可能包含多個(gè)方法的。
在接口中還可以定義常量。
接口絕不能含有實(shí)例域,也不能在接口中實(shí)現(xiàn)方法。(提供實(shí)例域和方法實(shí)現(xiàn)的任務(wù)應(yīng)該由實(shí)現(xiàn)接口的類(lèi)來(lái)完成)
假設(shè)希望使用Arrays類(lèi)的sort方法對(duì)Employee對(duì)象數(shù)組進(jìn)行排序,Employee類(lèi)就必須實(shí)現(xiàn)Comparable接口。
實(shí)現(xiàn)一個(gè)接口,通常需要下面兩個(gè)步驟:
1. 將類(lèi)聲明為實(shí)現(xiàn)給定的接口(使用關(guān)鍵字implements)
2. 對(duì)接口中的所有方法進(jìn)行定義
下面是具體代碼:
package com.ck.entity;
public class Employee implements Comparable<Employee>
private String name;
private double salary;
public Employee(String name, double salary) {
super();
this.name = name;
this.salary = salary;
}
public Employee() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [name=" + name + ", salary=" + salary + "]";
}
@Override
public int compareTo(Employee o) {
return Double.compare(salary, o.getSalary());
}
}
@Test
public void test1(){
Employee[] emps = new Employee[3];
emps[0] = new Employee("王五",2000);
emps[1] = new Employee("張三", 5000);
emps[2] = new Employee("李四", 4000);
Arrays.sort(emps);
for (Employee employee : emps) {
System.out.println(employee.toString());
}
}
3.3 接口的特性
1. 接口不是類(lèi),尤其不能使用new關(guān)鍵字實(shí)例化一個(gè)接口;
2. 雖然不能實(shí)例化接口,但可以聲明接口的變量:Comparable x = new Employee();
3. 如同使用instanceof檢查一個(gè)對(duì)象是否屬于某個(gè)特定類(lèi)一樣,也可以使用instanceof檢查一個(gè)對(duì)象是否實(shí)現(xiàn)了某個(gè)特定的接口:if(anObject instanceof Comparable){…}
4. 與可以建立類(lèi)的繼承關(guān)系一樣,接口也可以擴(kuò)展:public interface A{} public interface B extends A{}
5. 雖然接口中不能包含實(shí)例域或者靜態(tài)方法,但卻可以包含常量:public interface A{ double x=50; },與接口中的方法都自動(dòng)的被設(shè)置為public一樣,接口中的域?qū)⒈蛔詣?dòng)設(shè)為public static final
6. 每個(gè)類(lèi)只能擁有一個(gè)超類(lèi),但卻可以實(shí)現(xiàn)多個(gè)接口。public class A implement B,C{}
4 接口與抽象類(lèi)的區(qū)別
4.1 語(yǔ)法方面的區(qū)別
1. 抽象類(lèi)可以提供成員方法的實(shí)現(xiàn)細(xì)節(jié),而接口中只能存在public abstract方法;
2. 抽象類(lèi)中的成員變量可以是各種類(lèi)型的,而接口中的成員變量只能是public static final類(lèi)型的;
3. 接口中不能含有靜態(tài)代碼塊及靜態(tài)方法,而抽象類(lèi)可以有靜態(tài)代碼塊和靜態(tài)方法;
4. 一個(gè)類(lèi)只能繼承一個(gè)抽象類(lèi),但卻可以實(shí)現(xiàn)多個(gè)接口
4.2 設(shè)計(jì)方面的區(qū)別
抽象類(lèi)是對(duì)一種事物的抽象,即對(duì)類(lèi)的抽象;而接口是對(duì)行為的抽象。抽象類(lèi)是對(duì)整個(gè)類(lèi)整體進(jìn)行抽象,包括屬性、行為;接口是對(duì)類(lèi)局部(行為)進(jìn)行抽象。比如:飛機(jī)和鳥(niǎo)不是同類(lèi)的事物,但是它們都有一個(gè)共性---會(huì)飛。那么在設(shè)計(jì)的時(shí)候,可以將飛機(jī)設(shè)計(jì)為一個(gè)類(lèi)Plane,將鳥(niǎo)設(shè)計(jì)為一個(gè)類(lèi)Bird,但是不能將飛行這個(gè)特性也設(shè)計(jì)為一個(gè)類(lèi),因?yàn)樗皇且粋(gè)行為,并不是對(duì)一類(lèi)事物的抽象描述。此時(shí),可以將飛行設(shè)計(jì)為一個(gè)接口Fly,包含方法fly(),然后Plane和Bird分別根據(jù)自己的需要實(shí)現(xiàn)Fly這個(gè)接口。然后至于有不同種類(lèi)的飛機(jī),比如戰(zhàn)斗機(jī)、民用飛機(jī)等直接繼承Plane即可,對(duì)于鳥(niǎo)類(lèi)也是類(lèi)似的,不同種類(lèi)的鳥(niǎo)直接繼承Bird類(lèi)即可。(從這個(gè)例子中能看出,繼承是一個(gè)“是不是”的關(guān)系,而接口實(shí)現(xiàn)則是“有沒(méi)有、具備不具備”的關(guān)系)