Реализует против расширяет: когда использовать? Какая разница?

720

Пожалуйста, объясните простым для понимания языком или ссылкой на какую-нибудь статью.

Саад Масуд
источник
9
ссылка Этот пример позволил легко понять интерфейс и абстрактный класс, то есть реализовать и расширить в Java.
Обучение пользователей
extends является элементом пространства расширения
Goldname

Ответы:

736

extendsдля расширения класса.

implementsдля реализации интерфейса

Разница между интерфейсом и обычным классом заключается в том, что в интерфейсе нельзя реализовать ни один из объявленных методов. Только класс, который "реализует" интерфейс, может реализовать методы. Интерфейс C ++, эквивалентный интерфейсу, будет абстрактным классом (не ТОЧНО таким же, но в значительной степени).

Также Java не поддерживает множественное наследование для классов. Это решается с помощью нескольких интерфейсов.

 public interface ExampleInterface {
    public void doAction();
    public String doThis(int number);
 }

 public class sub implements ExampleInterface {
     public void doAction() {
       //specify what must happen
     }

     public String doThis(int number) {
       //specfiy what must happen
     }
 }

сейчас расширяю класс

 public class SuperClass {
    public int getNb() {
         //specify what must happen
        return 1;
     }

     public int getNb2() {
         //specify what must happen
        return 2;
     }
 }

 public class SubClass extends SuperClass {
      //you can override the implementation
      @Override
      public int getNb2() {
        return 3;
     }
 }

в этом случае

  Subclass s = new SubClass();
  s.getNb(); //returns 1
  s.getNb2(); //returns 3

  SuperClass sup = new SuperClass();
  sup.getNb(); //returns 1
  sup.getNb2(); //returns 2

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

tgoossens
источник
46
Интерфейс может содержать гораздо больше, чем объявления методов: постоянные поля, аннотации, интерфейсы и даже классы.
Филипп Рейхарт
это что-то вроде модулей и миксинов в ruby?
user2492854
@ user2492854 немного, но в интерфейсе не будет никаких реализованных методов. Это буквально описание интерфейса, а не реализация.
Роб Грант
34
Новая функция в Java 8 позволяет реализовать defaultповедение методов в интерфейсах, делая пользовательскую реализацию этих методов необязательной. Поэтому утверждение «вы можете только указывать методы, но не реализовывать их» является полностью правильным только для Java 7 и ниже .
ADTC
5
"extends - это расширение класса", немного сбивает с толку. Синус интерфейс и расширяет интерфейс тоже . Например:public interface ListIterator<E> extends Iterator<E>
Вэйхэн
78

Я заметил, у вас есть несколько вопросов C ++ в вашем профиле. Если вы понимаете концепцию множественного наследования от C ++ (имеется в виду классы, которые наследуют характеристики более чем от одного другого класса), Java не допускает этого, но у нее есть ключевое слово interface, которое похоже на чистый виртуальный класс в C ++. Как упоминалось многими людьми, вы extendкласс (и вы можете расширять только от одного), и вы implementинтерфейс - но ваш класс может реализовать столько интерфейсов, сколько вам нужно.

Т.е. эти ключевые слова и правила, регулирующие их использование, очерчивают возможности множественного наследования в Java (у вас может быть только один суперкласс, но вы можете реализовать несколько интерфейсов).

delicateLatticeworkFever
источник
51

Обычно реализует используемый для реализации интерфейса и расширяет используемый для расширения поведения базового класса или абстрактного класса.

extends : производный класс может расширять базовый класс. Вы можете переопределить поведение установленных отношений. Производный класс " является " типом базового класса

реализует : вы выполняете контракт. Класс, реализующий интерфейс, « имеет » возможность.

С выпуском Java 8 интерфейс может иметь методы по умолчанию в интерфейсе, который обеспечивает реализацию в самом интерфейсе.

Обратитесь к этому вопросу, чтобы узнать, когда использовать каждый из них:

Интерфейс против абстрактного класса (общий ОО)

Пример, чтобы понять вещи.

public class ExtendsAndImplementsDemo{
    public static void main(String args[]){

        Dog dog = new Dog("Tiger",16);
        Cat cat = new Cat("July",20);

        System.out.println("Dog:"+dog);
        System.out.println("Cat:"+cat);

        dog.remember();
        dog.protectOwner();
        Learn dl = dog;
        dl.learn();

        cat.remember();
        cat.protectOwner();

        Climb c = cat;
        c.climb();

        Man man = new Man("Ravindra",40);
        System.out.println(man);

        Climb cm = man;
        cm.climb();
        Think t = man;
        t.think();
        Learn l = man;
        l.learn();
        Apply a = man;
        a.apply();

    }
}

abstract class Animal{
    String name;
    int lifeExpentency;
    public Animal(String name,int lifeExpentency ){
        this.name = name;
        this.lifeExpentency=lifeExpentency;
    }
    public void remember(){
        System.out.println("Define your own remember");
    }
    public void protectOwner(){
        System.out.println("Define your own protectOwner");
    }

    public String toString(){
        return this.getClass().getSimpleName()+":"+name+":"+lifeExpentency;
    }
}
class Dog extends Animal implements Learn{

    public Dog(String name,int age){
        super(name,age);
    }
    public void remember(){
        System.out.println(this.getClass().getSimpleName()+" can remember for 5 minutes");
    }
    public void protectOwner(){
        System.out.println(this.getClass().getSimpleName()+ " will protect owner");
    }
    public void learn(){
        System.out.println(this.getClass().getSimpleName()+ " can learn:");
    }
}
class Cat extends Animal implements Climb {
    public Cat(String name,int age){
        super(name,age);
    }
    public void remember(){
        System.out.println(this.getClass().getSimpleName() + " can remember for 16 hours");
    }
    public void protectOwner(){
        System.out.println(this.getClass().getSimpleName()+ " won't protect owner");
    }
    public void climb(){
        System.out.println(this.getClass().getSimpleName()+ " can climb");
    }
}
interface Climb{
    public void climb();
}
interface Think {
    public void think();
}

interface Learn {
    public void learn();
}
interface Apply{
    public void apply();
}

class Man implements Think,Learn,Apply,Climb{
    String name;
    int age;

    public Man(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void think(){
        System.out.println("I can think:"+this.getClass().getSimpleName());
    }
    public void learn(){
        System.out.println("I can learn:"+this.getClass().getSimpleName());
    }
    public void apply(){
        System.out.println("I can apply:"+this.getClass().getSimpleName());
    }
    public void climb(){
        System.out.println("I can climb:"+this.getClass().getSimpleName());
    }
    public String toString(){
        return "Man :"+name+":Age:"+age;
    }
}

вывод:

Dog:Dog:Tiger:16
Cat:Cat:July:20
Dog can remember for 5 minutes
Dog will protect owner
Dog can learn:
Cat can remember for 16 hours
Cat won't protect owner
Cat can climb
Man :Ravindra:Age:40
I can climb:Man
I can think:Man
I can learn:Man
I can apply:Man

Важные моменты для понимания:

  1. Собака и Кошка - животные, и они расширены remember() и protectOwner(), делясь name,lifeExpentencyсAnimal
  2. Кошка может подняться (), а собака - нет. Собака может думать (), а кошка - нет . Эти конкретные возможности добавляются Catи Dogреализуются этой возможностью.
  3. Человек не животное, но он может Think,Learn,Apply,Climb

Просматривая эти примеры, вы можете понять, что

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

Равиндра Бабу
источник
1
Очень хорошо объяснил. Это просто щелкнуло. Огромное спасибо!
Эмир Мемик
Это действительно так? Я всегда думал, что «имеет» означает иметь что-то, обладать этим. Можно сказать, что у кошки есть способность к лазанию, но я бы сказал, перефразируйте ваш пример. Cat "- это" альпинист ", человек" - это "" мыслитель, ученик, альпинист ". Поскольку человек" является "мыслителем, он может делать то же, что и мыслитель. Это даже понятнее при работе с некоторыми протоколами - если вы есть дом, у него есть дверь, но он не реализует pushingHandle. Он также "является" MaterialObject, что означает, что он реализует интерфейс для подчинения гравитации; у него нет "GravityObeyingSkill" или чего-то подобного.
MatthewRock
Если человек мыслитель, я установлю связь с удлинителями, а не с орудиями. У мыслителя могут быть некоторые состояния и другие роли / функции, но я буду реализовывать способность мышления только с помощью интерфейса. IS A - это стандартный термин, используемый для наследования.
Равиндра Бабу
@Ravindrababu Большое спасибо за такое четкое объяснение.
Канудо
1
здорово объяснил!
Дари
43

extendsэто когда вы наследуете от базового класса (т.е. расширяете его функциональность).

implementsдля когда вы реализуете интерфейс .

Вот хорошее место для начала: интерфейсы и наследование .

Оливер Чарльзуорт
источник
24
И расширяет также для того, когда вы расширяете интерфейс :-).
Марк Питерс
34

А classможет только «реализовать» interface. Класс только "расширяет" a class. Аналогично, interfaceможет продлить другое interface.

А classможет продлить только один другой class. А classможет реализовать несколько interfaceс.

Если вместо этого вам больше интересно знать, когда использовать abstract classes и interfaces, обратитесь к этой теме: Интерфейс против абстрактного класса (общий OO)

Хари Менон
источник
2
Вы также можете расширить интерфейс.
Марк Питерс
2
А classможет реализовать только один interface. А classможет расширять несколько других классов. Я верю, что ты получил это задом наперед.
pb2q
Просто, чтобы уточнить комментарий от pb2q, ответ уже был отредактирован / исправлен. «Класс может расширять только один другой класс. Класс может реализовывать несколько интерфейсов» - это правильное утверждение.
wisbucky
29

Интерфейс - это описание действий, которые может выполнять объект ... например, когда вы нажимаете на выключатель света, свет включается, вам все равно, как, просто так и происходит. В объектно-ориентированном программировании интерфейс - это описание всех функций, которые должен иметь объект, чтобы быть «Х». Опять же, в качестве примера, все, что "ACTS LIKE" источник света, должно иметь метод turn_on () и метод turn_off (). Назначение интерфейсов состоит в том, чтобы позволить компьютеру применять эти свойства и знать, что объект типа T (независимо от интерфейса) должен иметь функции с именами X, Y, Z и т. Д.

Интерфейс - это структура / синтаксис программирования, которая позволяет компьютеру применять определенные свойства к объекту (классу). Например, скажем, у нас есть класс автомобилей, класс скутеров и класс грузовиков. Каждый из этих трех классов должен иметь действие start_engine (). То, как «двигатель запускается» для каждого транспортного средства, остается за каждым конкретным классом, но тот факт, что они должны иметь действие start_engine, является областью интерфейса .

Райан Эфенди
источник
4
Отличное объяснение; заслуживает большего признания.
Арвинд Мани
22

Как показано на рисунке ниже, класс расширяет другой класс, интерфейс расширяет другой интерфейс, но класс реализует интерфейс. введите описание изображения здесь

Для более подробной информации

JustCode
источник
16

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

Реализует : это используется для реализации интерфейса (родительский класс только с сигнатурами функций, но не их определениями) путем определения его в дочернем классе.

Существует одно специальное условие: «Что если я хочу, чтобы новый интерфейс был дочерним по отношению к существующему интерфейсу?». В вышеуказанном состоянии дочерний интерфейс расширяет родительский интерфейс.

Гуру
источник
15
  • А расширяет Б:

    A и B оба класса или оба интерфейса

  • А реализует Б

    A это класс, а B это интерфейс

  • Оставшийся случай, когда A - это интерфейс, а B - это класс, недопустим в Java.

Маркиз Лорн
источник
12

Implements используется для интерфейсов, а extends используется для расширения класса.

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

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

Еще несколько заметок:

интерфейс может расширять другой интерфейс.

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

Казекаге Гаара
источник
8

Оба ключевых слова используются при создании собственного нового класса на языке Java.

Разница: implementsозначает, что вы используете элементы интерфейса Java в своем классе. extendsозначает, что вы создаете подкласс базового класса, который вы расширяете. Вы можете расширить только один класс в своем дочернем классе, но вы можете реализовать столько интерфейсов, сколько захотите.

Обратитесь к странице документации оракула на интерфейсе для получения дополнительной информации.

Это может помочь уточнить, что такое интерфейс, и соглашения об их использовании.

Даниил
источник
7

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

Суть в том, что, хотя мы реализуем что-либо, это просто означает, что мы используем эти методы как есть. Нет возможности для изменения их значений и типов возвращаемых данных.

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

Нихил Арора
источник
Я читаю этот ответ, написанный мной спустя более 3 лет, 19 сентября. Клянусь, я не могу понять, что я написал. Я мог бы написать гораздо лучший ответ сейчас. Странная вещь.
Нихил Арора
7

Мы используем SubClass расширяет SuperClass только тогда, когда подкласс хочет использовать некоторые функциональные возможности (методы или переменные экземпляра), которые уже объявлены в SuperClass , или если я хочу немного изменить функциональность SuperClass (переопределение метода). Но скажем, например, у меня есть класс Animal ( SuperClass ) и класс Dog ( SubClass ), и есть несколько методов, которые я определил в классе Animal, например. doEat (); , doSleep (); ... и многое другое

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

А теперь представьте, однажды какой-то любитель Кошек входит в наше рабочее пространство и пытается расширить класс животных (кошки тоже едят и спят). Она создает объект Cat и начинает вызывать методы.

Но, скажем, кто-то пытается сделать объект класса животных. Вы можете сказать, как спит кошка, вы можете сказать, как ест собака, вы можете сказать, как пьет слон. Но это не имеет никакого смысла в создании объекта класса Animal. Потому что это шаблон, и мы не хотим никакого общего способа питания.

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

Итак, в заключение, Интерфейс - это не что иное, как абстрактный класс (чистый абстрактный класс), который не содержит никаких реализаций метода, а содержит только определения (шаблоны). Поэтому тот, кто реализует интерфейс, просто знает, что у него есть шаблоны doEat (); и doSleep (); но они должны определить свои собственные doEat (); и doSleep (); методы в соответствии с их потребностями.

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

Я поделюсь с вами фрагментом кода: вы попробуете его с разными наборами входов и посмотрите на результаты.

class AnimalClass {

public void doEat() {

    System.out.println("Animal Eating...");
}

public void sleep() {

    System.out.println("Animal Sleeping...");
}

}

public class Dog extends AnimalClass implements AnimalInterface, Herbi{

public static void main(String[] args) {

    AnimalInterface a = new Dog();
    Dog obj = new Dog();
    obj.doEat();
    a.eating();

    obj.eating();
    obj.herbiEating();
}

public void doEat() {
    System.out.println("Dog eating...");
}

@Override
public void eating() {

    System.out.println("Eating through an interface...");
    // TODO Auto-generated method stub

}

@Override
public void herbiEating() {

    System.out.println("Herbi eating through an interface...");
    // TODO Auto-generated method stub

}


}

Определенные интерфейсы :

public interface AnimalInterface {

public void eating();

}


interface Herbi {

public void herbiEating();

}
Шубхам Арья
источник
7

В самых простых терминах extends используется для наследования от класса, а реализации - для применения интерфейса в вашем классе.

расширяет :

public class Bicycle {
    //properties and methods
}
public class MountainBike extends Bicycle {
    //new properties and methods
}

реализует :

public interface Relatable {
    //stuff you want to put
}
public class RectanglePlus implements Relatable {
    //your class code
}

если у вас все еще есть путаница, прочитайте это: https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html https://docs.oracle.com/javase/tutorial/java/IandI/usinginterface.html

Иртеза Асад
источник
5

Классы и интерфейсы являются контрактами . Они предоставляют методы и свойства, на которые опираются другие части приложения.

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

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

extends используется, когда вы хотите заменить детали существующего контракта. Таким образом, вы заменяете один способ выполнения контракта другим способом. Классы могут расширять другие классы, а интерфейсы могут расширять другие интерфейсы.

Мартин Комишке
источник
3

Extendsиспользуется, когда вам нужны атрибуты родительского класса / интерфейса в вашем дочернем классе / интерфейсе, и implementsиспользуется, когда вам нужны атрибуты интерфейса в вашем классе.

Пример:

  1. Расширяет использование класса

    class Parent {

    }

    класс Child расширяет Parent {

    }

  2. Расширяет использование интерфейса

    интерфейс Parent {

    }

    Интерфейс Child расширяет Parent {

    }

  3. инвентарь

интерфейс A {

}

класс B реализует A {

}

Сочетание расширяет и реализует

interface A{

}

class B

{

}

class C implements A,extends B{

}
Alekya
источник
2

продолжается

  • класс расширяет только один класс
  • интерфейс расширяет один или несколько интерфейсов

инвентарь

  • класс реализует один или несколько интерфейсов
  • Интерфейсы "не может" реализует что-либо

абстрактные классы также действуют как классы с расширениями и реализациями

Юреш Карунанаяке
источник
0

Эти два ключевых слова непосредственно связаны с Наследством, это основная концепция ООП. Когда мы наследуем некоторый класс другому классу, мы можем использовать extends, но когда мы собираемся наследовать некоторые интерфейсы для нашего класса, мы не можем использовать extends, мы должны использовать инструменты и мы можем использовать ключевое слово extends для наследования интерфейса от другого интерфейса.

Кавинда Пушпита
источник