Поскольку эта тема не близка, я опубликую этот ответ, я надеюсь, что это поможет кому-то понять, почему Java не допускает множественное наследование.
Рассмотрим следующий класс:
public class Abc{
public void doSomething(){
}
}
В этом случае класс Abc ничего не расширяет, верно? Не так быстро, этот класс неявно расширяет класс Object, базовый класс, который позволяет всем работать в Java. Все является объектом.
Если вы попытаетесь использовать приведенный выше класс, вы увидите, что ваша IDE позволяет вам использовать такие методы, как: equals(Object o)
, toString()
и т. Д., Но вы не объявляли эти методы, они пришли из базового класса Object
Вы можете попробовать:
public class Abc extends String{
public void doSomething(){
}
}
Это нормально, потому что ваш класс не будет неявно расширяться Object
, но будет расширяться String
, потому что вы это сказали. Рассмотрим следующее изменение:
public class Abc{
public void doSomething(){
}
@Override
public String toString(){
return "hello";
}
}
Теперь ваш класс всегда будет возвращать «привет», если вы вызываете toString ().
Теперь представьте себе следующий класс:
public class Flyer{
public void makeFly(){
}
}
public class Bird extends Abc, Flyer{
public void doAnotherThing(){
}
}
Опять класс Flyer
неявно расширяет Object, у которого есть метод toString()
, у любого класса будет этот метод, поскольку все они расширяются Object
косвенно, поэтому, если вы вызываете toString()
из Bird
, что toString()
Java должен был бы использовать? От Abc
или Flyer
? Это произойдет с любым классом, который пытается расширить два или более классов, чтобы избежать такого «коллизии методов», они создали идею interface , в основном вы могли бы думать о них как о абстрактном классе, который не расширяет объект косвенно . Поскольку они абстрактные , они должны быть реализованы классом, который является объектом (вы не можете создать экземпляр интерфейса самостоятельно, они должны быть реализованы классом), поэтому все будет продолжайте работать нормально.
Чтобы отличать классы от интерфейсов, ключевое слово реализует зарезервировано только для интерфейсов.
Вы можете реализовать любой интерфейс, который вам нравится, в одном и том же классе, поскольку по умолчанию они ничего не расширяют (но вы можете создать интерфейс, который расширяет другой интерфейс, но, опять же, интерфейс «папа» не расширяет Object »), поэтому Интерфейс - это просто интерфейс, и они не пострадают от " colissions сигнатур методов ", если они это сделают, компилятор выдаст вам предупреждение, и вам просто нужно изменить сигнатуру метода, чтобы исправить это (подпись = имя метода + params + тип возвращаемого значения).
public interface Flyer{
public void makeFly(); // <- method without implementation
}
public class Bird extends Abc implements Flyer{
public void doAnotherThing(){
}
@Override
public void makeFly(){ // <- implementation of Flyer interface
}
// Flyer does not have toString() method or any method from class Object,
// no method signature collision will happen here
}