2009-12-23 119 views
0

是否可以在Java中創建抽象類的對象java中的抽象類

+1

這是一個初學者的問題,而是一個有效的。 – dmeister

+1

良好的形式和SO社區沒有lmgtfy答案的金星,再加上一些有用的直接解釋。 –

回答

1

這取決於你的意思。

如果你的意思是:「我可以有一個抽象類的實例」 - 當然;具體子類(抽象類的)的任何實例都隱含地是也是抽象超類型的實例

如果你的意思是:「我可以有一個抽象類的實例,而不定義一個具體的子類型」 - 是的,如果某個庫(例如javassist,cglib)爲你生成一個具體的子類型。

如果你的意思是「將下面的表達式所傳授」:

assert Modifier.isAbstract(x.getClass().getModifiers()); 

答案是否定的。

1

你不能實例化一個抽象類(在它上面調用new),如果這就是你的意思。

可能有子類的實例。這些對象也是抽象類的instanceof,這意味着你可以將它們投射到它。

3

試圖實例化一個抽象類,除非你提供的所有抽象方法的實現會在編譯時失敗(通過實現一個匿名內部類):如果你有一個抽象類,像這樣

Runnable r = new Runnable() { 
    public void run() { 
     //do something 
    } 
}; 
+0

您可能已經使用了一個包含抽象類(Runnable是一個接口)的示例... :) – NateS

4

public abstract class Foo 
{ 
    public void bar() 
    { 
     car(); 
    } 

    protected abstract void car(); 
} 

如果你能做到這一點:

final Foo foo; 

foo = new Foo(); 
foo.bar(); 

假如「汽車」方法沒有與之相關的代碼,那麼當「酒吧」方法稱爲「汽車」方法時會發生什麼?

但是,您可以這樣做:

class Star 
    extends Bar 
{ 
    protected void car() 
    { 
    } 
} 

,然後執行:

final Foo foo; 

foo = new Star(); 
foo.bar(); 

這個時候你有Foo類型的變量,可容納美孚的任何具體子類(一類就是不抽象是具體的)。現在當你調用「bar」方法時,它使用Foo中的方法,當調用「car」方法時,它使用Star中的方法。這是多態性的一個例子。

3

假設這是一個完整的新手問題,這裏就是抽象類是Java:

有在java中三種主要類型的類,接口抽象類。其中每一個都增加了特定於實際類定義的內容;

  • 接口定義的方法之一可以找到(,並且必須實現)中的一類。總之,接口定義了行爲。
  • 抽象類實現了一些功能,並在其上定義了額外的抽象方法必須由擴展類實現。使用抽象類與直接類繼承類似。
  • 就是你最可能已經熟悉的類。

使用任何可能的類類型有很多原因,但是最常見的是在現代Java代碼中,您將看到很多接口和一堆實現這些接口的類。

例子:類

考慮下面的類:

public class Cat { 
public void speak() { 
    System.out.println("Meow!"); 
} 
public void eat(Food f) { 
    System.out.println("Om nom nom, this "+f.getName()+" is delicious!"); 
} 
} 

這是一個非常簡單的類和每個Java編碼器,即使初學者的那種,都很熟悉。沒什麼特別的。然而,你有這樣一個問題:如果你有一個Dog基本上是一樣的,但它顯然是吠叫而不是喵?

實施例:抽象類

的 「CatDog」 問題可以用繼承來解決。傳統標準的繼承看起來像這樣:

public class Animal { 
public void eat(Food f) { 
    System.out.println("Om nom nom, this "+f.getName()+" is delicious!"); 
} 
} 

public class Cat extends Animal { 
public void speak() { 
    System.out.println("Meow!"); 
} 
} 

public class Dog extends Animal { 
public void speak() { 
    System.out.println("Bark! Bark!"); 
} 
} 

但是這裏存在一個問題:要真正使Cat喵或Dog樹皮,你必須有代碼檢查什麼樣的動物正是動物,將其轉換爲正確的類型,然後調用方法:

if (animal instanceof Dog) { 
((Dog) animal).speak(); 
} else if (animal instanceof Cat) { 
((Cat) animal).speak(); 
} 

正如你所看到的,這種代碼是完全沒有意義的!當然,我們希望能夠直接撥打animal.speak(),對吧?爲此,我們有抽象類!通過這種

public abstract class Animal { 
public void eat(Food f) { 
    System.out.println("Om nom nom, this "+f.getName()+" is delicious!"); 
} 
public abstract void speak(); 
} 

更換Animal類在上面的例子中你可以通過調用animal.speak()讓你Dog樹皮和Cat喵!太好了,不是嗎?

請注意,您也可以定義speak()的默認行爲Animal,然後就重寫方法CatDog,有時甚至有一定道理比我剛纔給這裏更多。

無論如何,還會出現另一個問題:如果您的DogAnimalPet? Java只允許單繼承來避免diamond inheritance problem,所以你不能只爲它們擁有另一個超類。你可以將它添加爲Animal的超類,但是再次,並非所有的動物都是寵物 - 我的院子裏池塘裏確實沒有河馬!

舉例:接口

由於接口只定義行爲,而不是實際實現他們(和這實際上是相關的關鍵字!),你可以使用接口來定義附加行爲的原班。讓我們假設寵物一般能在其他的事情來扶植,所以Pet接口會是這樣:

public interface Pet { 
void groom(Brush b); 
} 

現在只需添加implements PetDog和它現在groomable!只是爲了確保,你Dog類的第一行應該是這樣的:

public class Dog extends Animal implements Pet { 

現在新郎的Dog或任何其他Pet,你可以這樣做:

if (animal instanceof Pet) ((Pet) animal).groom(); 

這幾乎是它。作爲一個練習,嘗試執行Animal作爲接口;請注意,接口實際上可以擴展其他接口。

PS。枚舉和匿名內部類也可以被認爲是類的類型,但是它們並不是每個人在學習Java基礎知識後都應該知道的主要類。

0

不,它是不可能的。你需要創建一個擴展抽象類的類,然後你可以創建一個子類的對象。

請找到實例:

abstract class AbstractClass{ 

    public abstract String abstractMethod(String param1,String param2); 

    public void nonAbstractMethod(String param){ 
     System.out.println("Value of param is "+param); 
    } 
} 

class NonAbstractClass extends AbstractClass{ 
    public String abstractMethod(String param1,String param2){ 
     String param = param1 + param2; 
     return param; 
    } 
} 


public class DemoClass{ 

    public static void main(String[] args) { 
     NonAbstractClass nonAbstractClass = new NonAbstractClass(); 
     nonAbstractClass.abstractMethod("param1", "param2"); 
     nonAbstractClass.nonAbstractMethod("param1"); 
    } 
} 
+0

是且不是......擴展抽象類的類本身不能抽象,因爲這是真實的。 –