Понимание цели абстрактных классов в Java
Предположим, у меня есть два класса, A и B. класс A определяется как абстрактный, в то время как B расширяет этот абстрактный класс, и, наконец, я тестирую результат, и оба класса являются частью одного пакета.
public abstract class A {
protected abstract void method1();
protected void method2() {
System.out.println("This is Class A's method");
}
}
public class B extends A {
@Override
protected void method1() {
System.out.println("This is B's implementaiton of A's method");
}
}
и теперь, когда я проверить их:
B b = new B();
b.method1();
b.method2();
я получаю ожидаемый результат:
This is B's implementaiton of A's method
This is Class A's method
вопросы:
- какова цель
@Override
ключевое слово, потому что если я его опущу, это все работает по-прежнему. - если я не реализую абстрактный метод, я получаю ошибку компиляции. Так в чем же отличие от реализации интерфейса?
- кроме того, я могу реализовать
method2()
в B, а также. Затем выходные данные изменяются на то, что используется в B. не является ли это также переопределением метода родительского класса? Тогда какова цель явного определения метода как аннотация в классе а?
8 ответов
@Override
@Override был введен в Java 5 (и немного расширен в Java 6). Это только информативно. Он говорит: "Я должен переопределить то, что уже существует в родительском классе или интерфейсе.
IDE, как Eclipse, может предупредить вас, если нет такого родительского метода (например, если вы неправильно используете имя). В этом случае ваш метод не будет вызван (из-за неправильного написания).
но не беспокойтесь слишком много о он.
абстрактный класс vs интерфейс
абстрактный класс позволяет определить базовую функциональность, оставляя неопределенные части. Интерфейс не позволяет ничего реализовать. Вы можете запрограммировать все, кроме той части, которая действительно меняется в каждом случае. Поэтому, когда вам это нужно, вы наследуете и реализуете недостающую часть.
переопределить два метода
да. В Java вы можете переопределить все методы, не объявленные явно как финал в родительском классе. Все в порядке. Если вы хотите сделать его неизменяемым, вы можете объявить его окончательным. Например, если вы хотите объявить заказ, вы можете:
public abstract class Ordering<X>
{
abstract boolean isLower(X a, X b);
abstract boolean isEquals(X a, X b);
final boolean isGreater(X a, X b) {
return !isLower(a, b) && !isEquals(a, b);
}
}
конечно, может иметь смысл переопределить isGreater, чтобы реализовать его другим более эффективным способом (представьте, что это дорого сравнивать). Но есть сценарии, когда вы хотите предоставить базовые уже реализованные функции (а затем, когда абстрактные классы лучше, чем интерфейсы) или когда вы хотите заставить некоторые реализация (тогда, когда final ключевое слово показать полезно).
-
@Override
не является ключевым словом, это необязательный аннотации это помогает компилятору проверить, что вы действительно переопределяете метод. Если ты скажешь@Override
но нет метода переопределения, компилятор скажет вам, что вы, вероятно, сделали опечатку. Переименоватьmethod1
tomethod12
чтобы увидеть эффект. - интерфейс не может иметь никаких реализаций, в то время как абстрактный класс может реализовать несколько методов. Кроме того, интерфейсы не может иметь членов данных.
- определение метода как абстрактной означает, что производный класс должны обеспечить реализацию. Не объявляя его абстрактным, говорит, что производные классы просто can обеспечить свою собственную реализацию, но они не должны.
абстрактные классы позволяют хранить реализации базового уровня (наследование), а также создавать контракт, который гарантирует, что унаследованные классы будут реализовывать определенную функциональность (интерфейс) самостоятельно...
хотя никогда не будет экземпляра абстрактного класса, вы можете хранить общие функции между наследниками...
Я всегда думал о них как о интерфейсах, которые позволяют реализации базового уровня определенных методов...
основное различие между абстрактными классами и интерфейсами заключается в том, что интерфейсы определяют только интерфейс, а абстрактные классы также могут иметь реализацию и поля/свойства.
абстрактный класс можно рассматривать как отношение IS-a (например, лошадь-животное). Для интерфейса это в основном некоторая функция, которую может иметь класс (например, INavigable, ISortable).
также абстрактные методы не могут быть созданы (не интерфейсов).
переопределение функций - показать, что функция имеет реализацию базового класса.
также множественное наследование невозможно / рекомендуется с классами, поэтому max. использовать только один базовый класс и наследовать от интерфейсов для других функций.
какова цель ключевого слова @Override, потому что, если я его опущу, это все работает по-прежнему.
удобочитаемость.
Если я не реализовать абстрактный метод, я получаю ошибку компиляции. Так что разница в реализации интерфейса?
интерфейсы не позволяют включить код.
кроме того, я могу реализовать method2() в B. После выхода изменений что использовать в Б. Разве это не переопределяет родительский класс метод. Тогда какова цель явного определения метода Аннотация В классе а?
Да, он переопределяет родительский метод. Обычно вы определяете метод как абстрактный, чтобы оставить реализацию для ребенка (который должен ее реализовать или быть абстрактным). Если это не абстрактно, вы должны реализовать его.
What is the purpose of @Override keyword
это более позднее добавление Java, которое предназначено для слабого самоконтроля. Это аннотация, то есть класс библиотеки, а не ключевое слово.
So what is the difference to implementing an interface?
мало. Интерфейс-это класс, в котором все методы абстрактны. Кроме того, разрешен только один родитель класса, в то время как это может быть несколько интерфейсов. Также вы можете поместить членов в класс, но не в интерфейс.
Then what is the purpose of explicitly Defining a method abstract in Class A?
вы должны объявить его абстрактным только если у него нет тела. Требуется для JVM знать, что все потомки будут иметь его.
реальное использование входит в картину, когда у вас есть несколько классов реализации и method1 вызывается из method2. В этом случае после выполнения method2 будет выполнен method1 в соответствующем классе.
public abstract class A {
protected abstract void method1(int val);
protected void method2() {
System.out.println("This is Class A's method");
//Let us I calculated something here, may be sum of two ints
method1(//pass above calculated int);
}
}
public class B extends A {
@Override
protected void method1(int val) {
System.out.println("This is B's implementaiton of A's method");
//Here you may do this class specific manipulation on val.
}
}
Как и в классе C, вы можете манипулировать общими вычисленными.
этой статьи имеет некоторые хорошие концепции (и примеры) относительно названия вашего вопроса.
Абстрактные Классы - это классы, которые содержат один или несколько элементов абстрактные методы. Ан абстрактный метод - это метод, который объявлен, но не содержит реализации. Абстрактные Классы не может быть создан экземпляр и требует подклассов для предоставления реализаций для абстрактного методы.
предположим, что вы хотите определить класс с определенными методами, но для любой цели проектирования вашей программы / проекта вы хотите убедиться, что конкретный метод (Абстрактный Метод) должны выполняться, когда Абстрактный Класс продлевается.
в основном, цель Абстрактные Классы определить класс с методами, которые:
- должно быть объявлено (аннотация) на подкласс
- необязательно используются (не абстрактные) в подклассе
Дополнительного Комментария
- несколько лет назад я разработал приложение для Android (Java, а не Kotlin), и во время использования многих библиотек я испытал поведение расширения моих классов абстрактными классами и из-за поведения этого типа класса, Android Studio автоматически добавляется в мой код, все Абстрактные Методы это было частью Абстрактный Класс который я расширял.