Абстрактный класс
- Может ли абстрактный класс иметь конструктор()?
Да, абстрактные классы могут иметь конструкторы. Даже если вы не определите конструктор, JVM создаст один конструктор по умолчанию для абстрактного класса.
- Для чего нужен конструктор в абстрактном классе?
Основная цель конструктора — инициализировать вновь созданный объект. В абстрактном классе у нас есть переменная экземпляра, абстрактные методы и неабстрактные методы. Нам нужно инициализировать неабстрактные методы и переменные экземпляра, поэтому абстрактные классы имеют конструктор.
- Как будет вызываться конструктор в абстрактном методе, ведь мы не можем создать объект абстрактного класса?
Он вызывается с помощью цепочки кострукторов, т.е. когда мы создаем объект подкласса, будет вызван и конструктор абстрактного класса.
- Что произойдет, если абстрактный класс реализует интерфейс?
Абстрактный класс может пропустить реализацию одного или нескольких методов, определенных в интерфейсе, и это не вызовет никаких ошибок.
Это происходит потому, что класс abstract
по определению должен быть расширен sub-classes
, а когда подкласс расширяет класс abstract
, то мы можем обеспечить реализацию всех абстрактных методов.
class Main {
public static void main(String[] args) {
System.out.println("This is main class");
}
}
abstract class Bird implements Ifly{
}
interface Ifly{
public void fly();
}
Выход: Нет ошибок
This is main class
Обратите внимание, что как только абстрактный метод Bird расширяется, необходимо реализовать все абстрактные методы, включая методы интерфейса Ifly
.
class Main extends Bird{
public static void main(String[] args) {
System.out.println("This is main class");
}
}
abstract class Bird implements Ifly{
}
interface Ifly{
public void fly();
}
Выход: с ошибкой, так как мы не реализуем абстрактный метод fly()
.
Main.java:4: error: Main is not abstract and does not override abstract method fly() in Ifly
class Main extends Bird{
^
1 error
Интерфейс
- Если есть два интерфейса с одинаковыми методами, что произойдет, если оба они будут реализованы классом?
Если методы абстрактны и сигнатуры методов одинаковы (включая тип возврата), то реализующий класс должен будет переопределить только один метод, и никаких проблем не возникнет.
class HelloWorld implements Face,Anatomy {
public static void main(String[] args) {
System.out.println("Hello, World!");
HelloWorld w = new HelloWorld();
w.getName();
}
@Override
public void getName(){}
}
interface Face{
void getName();
}
interface Anatomy {
void getName();
}
Выход:
Hello, World!
Примечание:
Если оба метода имеют разные типы возврата, то реализующий класс должен будет переопределить оба метода.
Примечание:
Если в обоих интерфейсах есть метод по умолчанию с одинаковым именем, то это приведет к ошибке времени компиляции.
Когда типы возврата одинаковы:
class Main implements Face,Anatomy {
public static void main(String[] args) {
}
@Override
public void getName(){}
}
interface Face{
void getName();
default void getFaceOrientation(){
System.out.println("the default face shape fo Face interface");
}
}
interface Anatomy {
void getName();
default void getFaceOrientation(){
System.out.println("the default face shape of Anatomy interface");
}
}
Выход:
Main.java:4: error: types Face and Anatomy are incompatible;
class Main implements Face,Anatomy {
^
class Main inherits unrelated defaults for getFaceOrientation() from types Face and Anatomy
1 error
Когда типы возврата различны:
class Main implements Face,Anatomy {
public static void main(String[] args) {
}
@Override
public void getName(){}
}
interface Face{
void getName();
default void getFaceOrientation(){
System.out.println("the default face shape fo Face interface");
}
}
interface Anatomy {
void getName();
default String getFaceOrientation(){
return "the default face shape of Anatomy interface";
}
}
Выход
Main.java:4: error: types Anatomy and Face are incompatible;
class Main implements Face,Anatomy {
^
both define getFaceOrientation(), but with unrelated return types
1 error