2012-01-27 4 views
0

Я узнал, что мы не можем создать экземпляр абстрактного класса. Но сегодня я проверил некоторые коды, и я чувствую смущение.создать объект абстрактного класса! = Создать экземпляр абстрактного класса?

package MainPackage; 

abstract class abstractClass { 
    abstract abstractClass a_function(); 
} 

public class Src { 
    abstractClass m; 
    public abstractClass abstractClassTest() { 
     return m.a_function(); 
    } 
    public static void main(String args[]) { 
     System.out.println("Hello world!"); 
    } 
} 

Здесь я создать абстрактный класс abstractClass и вернуть его в функции abstractClassTest(). И он скомпилирован успешно без ошибок! IMO перед возвратом что-то, компьютер должен создать объект такого типа. И здесь он должен создать объект abstractClass до return m.function(), который я не могу понять. я думаю, что мы не можем создать экземпляр абстрактного класс означает, что мы не можем создать объект абстрактного класса или мы косяка нового класса (например. abstractClass m = new abstractClass() is illegal). Но из приведенных выше кодов кажется, что мы можем создать объект абстрактного класса. как он может это понять? Для кода abstractClass m, что делает компьютер, когда он видит код? Мы не можем сказать, что java создает экземпляр класса m для кода abstractClass m? и если java не создает экземпляр класса abstractClass, как он может вернуть объект abstractClass в код abstract abstractClass a_function();?

+0

Вы не *** создаете *** абстрактный класс, просто используя его ссылку. – Bhushan

+0

Обратите внимание, что ваш код * не * создает экземпляр любого объекта abstractclass. Если вы должны были создать подкласс абстрактного класса, вы можете создать его (abstractClass m = new childClass (...)), а затем m.a_function будет действительным. –

+0

Как вы отмечаете, вы не можете «новый» абстрактный класс. У вашего кода нет «нового» в любом месте - так где же проблема? – yshavit

ответ

5

Да, это должно скомпилировать без ошибок. Он бы выбросил NullPointerException на выполнение, хотя, если вы когда-либо вызывали abstractClassTest, потому что вы никогда не инициализируете переменную m для обращения к фактическому экземпляру. Для этого вам нужно создать класс бетон, который подклассифицирует ваш абстрактный.

Например:

public class ConcreteClass extends AbstractClass { 
    @Override AbstractClass a_function() { 
     return this; 
    } 
} 

public class Src { 
    private AbstractClass m = new ConcreteClass(); 

    public AbstractClass abstractClassTest() { 
     return m.a_function(); 
    } 
    public static void main(String args[]) { 
     new Src().abstractClassTest(); 
    } 
} 

Обратите внимание, что ничто в вашем коде не создает экземпляр абстрактного класса. Просто потому, что у вас есть переменная этого типа, это не означает, что был создан объект этого типа.

+0

Если вы попытаетесь инициализировать переменную экземпляром абстрактного класса напрямую, вы получите ошибку компиляции. –

+3

@SpencerKormos: Да, OP, похоже, уже это знает. –

+0

Просто пометка для полноты. :-) –

0

Вы не можете напрямую создать экземпляр абстрактного класса, и ваш код на самом деле этого не делает. То, что у вас есть, - это просто ссылка на какой-либо подкласс или другой из вашего абстрактного класса, и когда вы приходите для создания экземпляра 'm', вам нужно будет предоставить конкретный конкретный подкласс.

Вы получаете аналогичную модель с интерфейсами. Это вполне законно писать, например:

List m; 
... 
m.size(); 

но когда вы пришли в экземпляр, вы могли бы сделать это с реализующего подкласса, например:

List m; 
... 
m = new ArrayList(); 
... 
m.size(); 

Обратите внимание, как при конкретизации, мы используем ArrayList, not List (это просто интерфейс).

1

m никогда не назначается, и вы никогда не пытаетесь создать экземпляр нового abstractClass с новым ключевым словом. Если ваш код когда-либо на самом деле попал в abstractClassTest, вы бы просто получили исключение нулевого указателя. Я думаю, что вы можете смешивать объявление переменной и фактически придавать ей значение.

Смежные вопросы