Java之路:抽象類
抽象類
在Java中可以建立一種類專門用來做父類,這種類稱為“抽象類”。抽象類實際上也是一個類,只是與之前的普通類相比,內部新增了抽象方法。
1、抽象方法
抽象方法是隻宣告而未實現的方法。
例:
void f(); // 只有宣告,沒有實現。
2、抽象類的定義與使用
(1)抽象類和抽象方法都必須用abstract關鍵字來修飾;
(2)抽象類不能直接例項化,也就是不能直接用new關鍵字去產生物件;
(3)抽象類定義時抽象方法只需宣告,而不需實現;
(4)含有抽象方法的類必須被宣告為抽象類,抽象類的子類必須覆寫所有的抽象方法後才能被例項化,否則這個子類還是個抽象類。
(5)抽象類可以定義普通方法,普通方法可以有方法體。
例:
public abstract class Book {
private String bookName = "《Java程式設計思想》"; // 定義屬性:書名
public void printName() { // 定義普通方法:列印書名
System.out.println(bookName);
}
public abstract void f(); // 定義一個抽象方法
public static void main(String[] args) {
Book b = new Book (); // 錯誤,抽象類無法例項化物件
}
}
【結果】
其實,抽象類也就是比普通類多了一些抽象方法而已。 如果說一個類的物件可以被例項化,那麼就表示這個物件可以呼叫類中的屬性和方法,但是抽象類中存在抽象方法,而抽象方法沒有方法體,沒有方法體的方法自然無法使用了。
(6)抽象類必須有子類,子類使用extends繼承抽象類,一個子類只能夠繼承一個抽象類;子類(如果不是抽象類),則必須要全部覆寫抽象類中的全部抽象方法;如果想要例項化抽象類的物件,則可以使用子類進行物件的向上轉型來完成。
例:
abstract class Person //定義一抽象類Person
{
String name;
int age;
String occupation;
public abstract String talk();//宣告一個抽象方法talk()
}
class Student extends Person //Student類繼承自Person類
{
public Student(String name,int age,String occupation)
{
this.name=name;
this.age=age;
this.occupation=occupation;
}
public String talk() //覆寫抽象方法talk()
{
return"學生——>姓名:"+this.name+",年齡:"+this.age+",職業:"+this.occupation+"!";
}
}
public class AbstractClassDemo
{
public static void main(String[] args)
{
Student s=new Student("張三",20,"學生"); //建立Student類物件
Person p = new Student("王五",22,"學生"); // 向上轉型為Person類
System.out.println(p.talk()); //呼叫被覆寫過的方法
System.out.println(s.talk()); //呼叫被覆寫過的方法
}
}
【結果】
(7)抽象類中可以有構造方法。
與一般類相同,在抽象類中也可以擁有構造方法,但是這些構造方法必須在子類中被呼叫,並且子類例項化物件的時候依然滿足類繼承的關係,先預設呼叫父類的構造方法,而後再呼叫子類的構造方法,畢竟抽象類之中還是存在屬性的,只不過這個抽象方法無法直接被外部例項化物件的時候所使用。
abstract class Person //定義一抽象類Person
{
String name;
int age;
String occupation;
public Person(String name, int age, String occupation) { // 定義一構造方法
this.name=name;
this.age=age;
this.occupation=occupation;
}
public abstract String talk();//宣告一個抽象方法talk()
}
class Student extends Person //Student類繼承自Person類
{
public Student(String name,int age,String occupation)
{
super(name, age, occupation); // 子類必須先呼叫抽象類的構造方法
this.name=name;
this.age=age;
this.occupation=occupation;
}
public String talk() //覆寫抽象方法talk()
{
return"學生——>姓名:"+this.name+",年齡:"+this.age+",職業:"+this.occupation+"!";
}
}
public class AbstractClassDemo
{
public static void main(String[] args)
{
Student s=new Student("張三",20,"學生"); //建立Student類物件s
Person p = new Student("王五",22,"學生"); // 向上轉型為Person類
System.out.println(p.talk()); //呼叫被覆寫過的方法
System.out.println(s.talk()); //呼叫被覆寫過的方法
}
}
【結果】
綜上可知,抽象類也可以像普通類一樣,有構造方法、一般方法和屬性,更重要的是還可以有一些抽象方法,需要子類去實現,而且在抽象類中宣告構造方法後,在子類中必須明確呼叫。
(8)抽象類不能夠用final定義。
使用final定義的類不能有子類,而抽象類使用的時候必須有子類,這是一個矛盾的問題,所以抽象類上不能出現final定義。
(9)在外部抽象類上無法使用static宣告,但是內部抽象類卻可以使用static定義,使用static定義的內部抽象類就表示一個外部類。
例:
abstract class Book { // 外部抽象類無法用static宣告
public abstract void print(); // 抽象方法
static abstract class CD { // 靜態內部抽象類,相當於一個外部類
public abstract void get(); // 抽象方法
}
}
class JavaCD extends Book.CD { // 繼承靜態內部抽象類
@Override
public void get() { // 重寫靜態內部抽象類的抽象方法
System.out.println("Java學習!");
}
}
public class StaticInnerAbstractClass {
public static void main(String[] args) {
Book.CD cd = new JavaCD(); // 例項化物件,向上轉型為父類CD
cd.get();
}
}
【結果】
(10)抽象類之中可以沒有抽象方法,但即便沒有抽象方法的抽象類也不能夠直接通過關鍵字new例項化。
例:
abstract class Book { // 沒有抽象方法的抽象類
}
public class StaticInnerAbstractClass {
public static void main(String[] args) {
Book b = new Book(); // 錯誤,無法例項化
}
}
【結果】