Почему нельзя использовать новое ключевое слово для инициализации абстрактного класса в Java? - PullRequest
6 голосов
/ 07 сентября 2011

Я где-то читал, что мы не можем инициализировать интерфейс, например:

interface MyInterface{};

И следующий код определенно недопустим:

MyInterface m = new MyInterface();

И, насколько я помню, текст, который я прочитал, сказал: потому что ключевое слово new используется для выделения памяти для членов класса; поэтому в случае интерфейса у нас есть только абстрактные функции, поэтому в интерфейсе нечего выделять; поэтому инициализация интерфейса запрещена.

Хорошо, это имеет смысл для меня.

Но в случае абстрактного класса нам разрешено объявлять и определять абстрактные функции, неабстрактные функции, а также обычные переменные, так почему же нам также не разрешено инициализировать абстрактный класс? И из-за этого мне было интересно, когда и как переменные в абстрактном классе, если таковые имеются, выделяются памяти?

Ответы [ 10 ]

15 голосов
/ 07 сентября 2011

Ни один объект никогда не является экземпляром "просто" абстрактного класса - это всегда экземпляр класса конкретный . В противном случае вы могли бы вызвать абстрактные методы ... и не было бы никакой реализации, которая будет вызвана.

Переменные в абстрактном классе распределяются так же, как и переменные любого другого класса, который оказывается суперклассом фактического класса, который инициализируется - они живут «с» переменными из другого классы в иерархии, в основном.

РЕДАКТИРОВАТЬ: Чтобы уточнить, это концептуальное ограничение столько же, сколько реализация одно. Абстрактный класс обычно содержит абстрактные методы, что делает его абстрактным. Смысл абстрактных методов состоит в том, чтобы позволить вызывающей стороне проверять во время компиляции, что метод будет там, даже если абстрактный класс не обеспечивает реализацию. ВМ гарантирует, что является реализацией, предотвращая создание "просто" абстрактных классов.

Теперь абстрактные классы могут также использоваться для предотвращения создания экземпляров, даже если нет никаких абстрактных методов - по сути, фундаментальный момент абстрактного класса в том, что это тот, который не может * 1022 быть непосредственно созданным; могут быть созданы только конкретные подклассы.

5 голосов
/ 07 сентября 2011

Когда вы говорите «инициализировать», вы на самом деле имеете в виду две разные вещи: распределение и построение. Выделение - это процесс получения памяти для объекта; Строительство - это процесс воплощения самого объекта в жизнь.

Как вы правильно заметили, ваш класс интерфейса не требует памяти. Но дело не в этом. Абстрактный класс не может быть создан , потому что он ... ну, абстрактный. Не существует объекта абстрактного типа. И интерфейсы абстрактные.

Думайте о Мерседесе как о абстрактном автомобиле. Вы можете купить Mercedes, но вы не можете купить абстрактный автомобиль - это не имеет смысловой смысл. Любой автомобиль, который вы могли себе представить, должен быть конкретного типа.


Редактировать: Может быть полезно подумать , почему класс может быть абстрактным:

  • Потому что объявлено abstract class. Это заставляет его абстрактно утончаться указом без объяснения причин.

  • Поскольку он имеет абстрактные функции-члены: функция-член не реализована, и конкретный производный класс должен обеспечивать реализацию.

  • Поскольку он объявлен interface: Это морально эквивалентно "все функции-члены абстрактны, и нет объектов-членов". (Наличие отдельного ключевого слова для этого позволяет интерфейсам обойти ограничения одиночного наследования.)

3 голосов
/ 07 сентября 2011

Класс abstract - это класс, который еще не закончен и обычно имеет абстрактные члены (хотя это не обязательно).Таким образом, вы не можете создать экземпляр абстрактного класса.Это определяется языком.

3 голосов
/ 07 сентября 2011

В этом смысл абстрактного класса: быть базовым классом для других классов. Он специально разработан для создания экземпляров , а не .

Большинство абстрактных классов имеют абстрактные методы, которые не имеют реализации. Как бы вы назвали такой метод, если бы вы создали экземпляр самого абстрактного класса?

Когда вы используете new для создания нового экземпляра подкласса абстрактного класса, память, необходимая для базового абстрактного класса, также будет выделена.

1 голос
/ 07 сентября 2011

абстрактные классы не заполнены. у них есть абстрактные методы, которые не реализованы. что произойдет, если вы попытаетесь вызвать один из них?

переменные абстрактного класса расположены в памяти конкретным экземпляром класса.

1 голос
/ 07 сентября 2011

Абстрактный класс - это класс, который объявлен абстрактным - он может включать или не включать абстрактные методы. Абстрактные классы не могут быть созданы , но они могут быть разделены на подклассы.

Если класс включает абстрактные методы, сам класс должен быть объявлен как абстрактный.

http://download.oracle.com/javase/tutorial/java/IandI/abstract.html

0 голосов
/ 07 сентября 2011

Кстати, даже если ваш интерфейс пуст, вы должны будете предоставить пустую реализацию:

Serializable x = new Serializable () {};

Пустые фигурные скобки будутпонадобиться и для абстрактного класса.Я не могу думать о необходимости этих конструкций.

0 голосов
/ 07 сентября 2011

Может быть, иллюстрация с некоторым кодом может быть полезной.

abstract class AC{
    abstract public void m();
}

class Main{
    public static void main(String[] a){
        AC obj = new AC();
        obj.m();  /* Nothing to execute. */
    }
}

Так что это поведение должно быть запрещено.

0 голосов
/ 07 сентября 2011

Когда вы создаете экземпляр класса, вы выделяете память для нескольких аспектов класса, включая область для методов (это значительно сложнее, чем это). У абстрактных классов нет определений для некоторых методов, поэтому мы не можем указывать на реальные методы.

Абстрактные классы содержат - хотя бы частично - методы без определений. Вы не можете вызвать их, потому что нет кода для запуска.

0 голосов
/ 07 сентября 2011

Переменные в абстрактном классе выделяются, когда ключевое слово new используется для класса, extends абстрактного класса.

Так что, если у вас нет класса, расширяющего ваш абстрактный класс, они никогда не будут выделены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...