Подтвердить что ты не робот

Расширяет ли абстрактный класс объект?

Я читал о различии между интерфейсами и абстрактными классами, но это сбивает с толку. Рассмотрим этот интерфейс и класс.

interface I {
    public int hashCode();
    public boolean equals(Object obj);
}

class B implements I {
    // Works Fine
}

Здесь он работает отлично, и мне не нужно переопределять методы интерфейса, потому что Object является супер-классом B, и эти методы реализованы в нем.

Теперь рассмотрим эти

abstract class A {
    public abstract int hashCode();
    public abstract boolean equals(Object obj);
}

class C extends A {
    // Compile error because methods are not overridden
}

Почему это приведет к ошибке компиляции? Означает ли это, что объект не является суперклассом для абстрактного класса? Или я пропустил какой-то момент?

4b9b3361

Ответ 1

Это приводит к ошибке компиляции, потому что по определению абстрактные функции должны быть реализованы вниз по течению в цепочке наследования. Вы создали требование, которое они должны быть реализованы в подклассе A.

Класс C не реализует эти методы, поэтому сбой компиляции.

Object является суперклассом абстрактных классов... но это не подкласс, а подклассы отвечают за реализацию абстрактных функций.

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

Существуют случаи, когда вы не можете, например, дегенеративный/плохой дизайн, или примеры, подобные этому, в то время как выкрикиваете языковые функции.

Ответ 2

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

В качестве пояснения для вашей ситуации попробуйте определить A следующим образом:

abstract class A {
    //public abstract int hashCode();
    //public abstract boolean equals(Object obj);
}

class C extends A {
    // no compile error because no abstract methods have to be overridden
}

В этом случае оба A и C наследуют реализацию этих методов из Object и не возникает ошибка компиляции.

Ответ 3

Объект является суперклассом всех классов, абстрактным или нет.

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

Это не имеет ничего общего с классом Object. Вы получите такое же поведение, если сами создадите все классы:

public class A {

   public int someMethod () {
       return 1;
   }
}

public abstract class B extends A {
   public abstract int someMethod ();
}

public class C extends B {

}

Это даст ошибку компиляции The type C must implement the inherited abstract method B.someMethod(), хотя A уже реализует ее.

Ответ 4

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

На самом деле есть некоторые (необычные) причины, которые вы, возможно, захотите. Например, если вы хотите убедиться, что все, кто использует класс A, внедрили свои равные и хэш-коды, вместо того, чтобы полагаться на версию объекта, вы могли бы это сделать.

Фактическое объяснение поведения состоит в том, что для расширения класса A вам необходимо выполнить все требования, которые вам предлагает класс A.

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

Здесь нет ничего особенного в Object:

abstract class A {
    public abstract int hashCode();
    public abstract boolean equals(Object obj);
    public void test() {

    }
 }

 abstract class B extends A {
     public abstract void test();
 }  

Теперь, если вы попытаетесь определить:

class C extends B {
    public int hashCode() { return 1; }
    public boolean equals(Object ob) { return false; }
}

Тогда это не будет означать, что C is not abstract and does not override abstract method test() in B.

Ответ 5

В вашем абстрактном классе есть только виртуальные методы (методы без реализации). Это означает, что они существуют в интерфейсе класса, поэтому кто-то действительно может их назвать. Такой вызов в вашем случае против hashCode или equals приведет к ошибке выполнения, поскольку эти методы не реализованы. Компилятор предотвращает это из-за ошибки компилятора.

Ответ 6

Да, объект - суперкласс абстрактного класса. Вы можете использовать аннотацию @Override, чтобы помочь вам.

См., нет ошибки в следующем коде:

abstract class A 
{   
    @Override
    public abstract int hashCode();

    @Override
    public abstract boolean equals(Object obj);
}

Ответ 7

Каждый класс расширяет Object. Даже класс abstract расширяет Object, но абстрактный класс является неполным. Вы не можете создавать экземпляр абстрактного класса, и любой класс, который расширяет абстрактный класс, должен либо предоставить все отсутствующие методы, либо также должен быть объявлен абстрактным.

Это приведет к ошибке компиляции?

Попробуйте и посмотрите!

Ответ 8

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

Ответ 9

Всякий раз, когда вы расширяете абстрактный класс, вы должны убедиться, что ВСЕ методы в абстрактном классе должны быть реализованы в подклассе, иначе это приведет к ошибке компиляции.

Ответ 10

Да абстрактный класс расширяет класс объекта. И он наследует свойства класса объекта. Здесь не следует путать, что абстрактный класс не может быть создан. Это произойдет в подклассе абстрактного класса, но в абстрактном классе мы можем создать экземпляр класса объекта и переопределить базовую реализацию. Таким образом, класс объекта может быть унаследован от абстрактного класса.