Интерфейсы и абстрактные классы нельзя никогда создавать. То, что вы можете сделать, как в своем примере, - это создать конкретный класс, но назначить полученный объект интерфейсу.
Рассмотрим следующую иерархию классов:
IBlah
^
|
AbstractBlah
^
|
BlahImpl
Если IBlah
является интерфейсом и AbstractBlah
является абстрактным классом, а BlahImpl
является конкретным классом, следующие строки кода недопустимы:
IBlah blah1 = new IBlah();
IBlah blah2 = new AbstractBlah();
AbstractBlah blah3 = new AbstractBlah();
Допустимы следующие строки кода:
IBlah blah1 = new BlahImpl();
AbstractBlah blah3 = new BlahImpl();
Таким образом, вы можете только создавать конкретный класс, но назначенная ему переменная может быть любым супертипом (родительским классом или интерфейсом, реализуемым классом) конкретного класса.
Вы можете обращаться к конкретному классу и использовать его через интерфейс или переменную абстрактного класса. Фактически это поощряется, поскольку программирование абстрактного класса (или интерфейса) делает ваш код более гибким.
Можно создать конкретный класс из интерфейса или абстрактного класса на месте. Итак, если у нас есть такой интерфейс:
interface IBlah {
void doBlah();
}
Этот интерфейс может быть реализован и реализован одним махом следующим образом:
IBlah blah = new IBlah() {
public void doBlah() {
System.out.println("Doing Blah");
}
};