code

Java 인터페이스는 다중 상속을 어떻게 시뮬레이션합니까?

codestyles 2020. 10. 20. 07:40
반응형

Java 인터페이스는 다중 상속을 어떻게 시뮬레이션합니까?


저는 "The Java Tutorial"(두 번째)을 읽고 있습니다. 방금 인터페이스 섹션을 살펴 봤지만 Java 인터페이스가 다중 상속을 시뮬레이션하는 방법을 여전히 이해하지 못합니다. 책에있는 것보다 더 명확한 설명이 있습니까?


도메인에 트럭과 주방이라는 두 가지 항목이 있다고 가정합니다.

트럭에는 driveTo () 메서드가 있고 Kitchens에는 cook () 메서드가 있습니다.

이제 Pauli가 배달 트럭 뒤에서 피자를 판매하기로 결정했다고 가정 해 보겠습니다. 그는 driveTo ()와 cook ()을 함께 할 수있는 것을 원합니다.

C ++에서 그는이를 위해 다중 상속을 사용합니다.

Java에서는 너무 위험하다고 간주되어 메인 클래스에서 상속 할 수 있지만 모든 의도와 목적을위한 필드 나 메서드 구현없이 추상 클래스 인 인터페이스에서 동작을 "상속"할 수 있습니다.

따라서 Java에서는 위임을 사용하여 다중 상속을 구현하는 경향이 있습니다.

Pauli는 트럭을 하위 클래스로 만들고 kitchen이라는 멤버 변수에서 트럭에 부엌을 추가합니다. 그는 kitchen.cook ()을 호출하여 Kitchen 인터페이스를 구현합니다.

class PizzaTruck extends Truck implements Kitchen {
   Kitchen kitchen;

   public void cook(Food foodItem) {
      kitchen.cook(foodItem);
   }
}

그는 이제 다음과 같은 일을 할 수 있기 때문에 행복한 사람입니다.

pizzaTruck.driveTo(beach);
pizzaTruck.cook(pizzaWithExtraAnchovies);

좋아,이 어리석은 이야기는 다중 상속의 시뮬레이션이 아니라는 점을 지적하는 것이 었습니다. 계약을 상속 할 수만 있고 인터페이스라고하는 빈 추상 기본 클래스에서만 상속한다는 단서가있는 실제 다중 상속입니다.

(업데이트 : 기본 메소드 인터페이스가 이제 상속 될 일부 동작을 제공 할 수 있음)


여러 부모로부터 구현 세부 정보를 상속하는 하나의 클래스 측면에서 여러 상속을 로컬로보기 때문에 혼란 스러울 수 있습니다. 이것은 자바에서는 불가능합니다 (그리고 종종 가능한 언어에서 남용으로 이어집니다).

인터페이스의 다중 상속 허용 유형 , 예를 들면이 class Waterfowl extends Bird implements Swimmer그것 인 것처럼 다른 클래스에서 사용할 수있는 Bird 것처럼이했다 Swimmer. 이것이 다중 상속의 더 깊은 의미입니다. 하나의 객체가 한 번에 관련되지 않은 여러 클래스에 속한 것처럼 작동하도록 허용합니다.


다음은 Java의 인터페이스를 통해 다중 상속을 달성하는 방법입니다.

무엇을 달성해야합니까?
클래스 A는 B, C를 확장합니다. // 이것은 자바에서 직접 가능하지 않지만 간접적으로 달성 할 수 있습니다.

class B{
   public void getValueB(){}
}

class C{
   public void getValueC(){}
}


interface cInterface{
   public getValueC();
}

class cChild extends C implemets cInterface{
    public getValueC(){

      // implementation goes here, call the super class's getValueC();

    }
}


// Below code is **like** class A extends B, C 
class A extends B implements cInterface{
   cInterface child =  new cChild();
   child.getValueC();
}

아래 두 인터페이스가 주어지면 ...

interface I1 {
  abstract void test(int i);
}
interface I2 {
  abstract void test(String s);
}

아래 코드를 사용하여이 두 가지를 모두 구현할 수 있습니다.

public class MultInterfaces implements I1, I2 {
  public void test(int i) {
    System.out.println("In MultInterfaces.I1.test");
  }
  public void test(String s) {
    System.out.println("In MultInterfaces.I2.test");
  }
  public static void main(String[] a) {
    MultInterfaces t = new MultInterfaces();
    t.test(42);
    t.test("Hello");
  }
}

두 개체를 확장 할 수 없지만 두 개의 인터페이스를 구현할 수 있습니다.


인터페이스는 다중 상속을 시뮬레이션하지 않습니다. Java 제작자는 다중 상속이 잘못되었다고 생각했기 때문에 Java에는 그런 것이 없습니다.

두 클래스의 기능을 하나로 결합하려면 개체 구성을 사용하십시오.

public class Main {
    private Component1 component1 = new Component1();    
    private Component2 component2 = new Component2();
}

그리고 특정 메서드를 노출하려면 해당 메서드를 정의하고 해당 컨트롤러에 호출을 위임하도록합니다.

여기에서 인터페이스가 편리 할 수 있습니다. Component1interface Interface1Component2구현하고을 구현 Interface2하면 다음을 정의 할 수 있습니다.

class Main implements Interface1, Interface2

따라서 컨텍스트가 허용하는 곳에서 객체를 상호 교환 적으로 사용할 수 있습니다.


도대체 무슨 일이 일어나고 있는지 이해하려는 자바 스크립트 개발자의 관점에서 볼 때, 몇 가지를 지적하고 싶습니다. 표를 벗어난 방법.

인터페이스는 정말 간단합니다. 어리 석고, 엄청나게 간단합니다. 사람들이 처음에 생각하는 것만 큼 어리 석고, 엄청나게 간단합니다. 그래서이 정확한 주제에 대해 중복 질문이 많은 이유는 그것들을 사용하는 한 가지 이유가 자신보다 더 많이 만들려고 애쓰는 사람들에 의해 명확하지 않기 때문입니다. 내가 노출 된 모든 Java 서버 측 코드베이스에서 널리 사용되는 오용입니다.

그렇다면 왜 그것들을 사용하고 싶습니까? 대부분의 경우 그렇지 않습니다. 많은 사람들이 생각하는 것처럼 항상 사용하고 싶지는 않을 것입니다. 그러나 당신이 원할 때에 도달하기 전에 그들이 아닌 것에 대해 이야기합시다.

인터페이스는 다음이 아닙니다.

  • 어떤 식 으로든 Java에없는 모든 종류의 상속 메커니즘에 대한 해결 방법입니다. 그들은 상속과 관련이 없으며 결코하지 않았으며 상속과 같은 것을 시뮬레이션하지도 않습니다.
  • 필연적으로 당신이 쓴 내용에 도움이되는 것입니다. 다른 사람이 당신의 내용에 의해 인터페이스 될 무언가를 작성하는 데 도움이됩니다.

첫눈에 생각하는 것처럼 정말 간단합니다. 사람들은 항상 어리석게 오용하기 때문에 요점이 무엇인지 이해하기 어렵습니다. 단지 검증 / 테스트 일뿐입니다. 인터페이스를 준수하고 작동하는 내용을 작성하면 해당 "구현"코드를 제거해도 아무 것도 손상되지 않습니다.

그러나 인터페이스를 올바르게 사용하고 있다면 제거하고 싶지 않을 것입니다. 인터페이스가 있으면 다음 개발자가 다른 데이터베이스 또는 웹 서비스 집합에 대한 액세스 계층을 작성하는 도구를 제공하므로 나머지 앱을 계속 사용할 수 있습니다. 예상대로 100 % 완전한 인터페이스를 얻을 때까지 클래스가 실패한다는 것을 알고 있기 때문에 사용합니다. 모든 인터페이스는 클래스의 유효성을 검사하고 약속 한대로 인터페이스를 실제로 구현했는지 확인하는 것입니다. 더 이상은 없습니다.

그들은 또한 휴대용입니다. 인터페이스 정의를 노출함으로써 노출되지 않은 코드를 사용하려는 사람들에게 객체가 올바르게 사용하기 위해 준수 할 일련의 메소드를 제공 할 수 있습니다. 인터페이스를 구현할 필요가 없습니다. 그들은 메모장 종이에 적어두고 다시 확인할 수 있습니다. 그러나 인터페이스를 사용하면 해당 인터페이스의 적절한 버전을 갖기 전까지는 아무것도 작동하지 않을 것이라는 보장이 더 많습니다.

그렇다면 한 번 이상 구현되지 않을 인터페이스가 있습니까? 완전히 쓸모가 없습니다. 다중 상속? 그 무지개에 도달하지 마십시오. Java는 애초에 이유 때문에이를 피하고 복합 / 집계 객체는 어쨌든 여러면에서 더 유연합니다. 인터페이스가 다중 상속이 허용하는 방식으로 모델링하는 데 도움이되지 않는다는 말은 아니지만 실제로는 어떤 형태 나 형태로든 상속이 아니므로 그렇게 보여서는 안됩니다. 설정 한 모든 메서드를 구현할 때까지 코드가 작동하지 않음을 보장하는 것입니다.


매우 간단합니다. 한 유형에 둘 이상의 인터페이스를 구현할 수 있습니다. 예를 들어, List그것 의 구현 이 또한 인스턴스 Deque(Java는 ... LinkedList) 일 수 있습니다.

여러 부모로부터 구현상속 할 수 없습니다 (예 : 여러 클래스 확장). 선언 (메소드 서명)은 문제가되지 않습니다.


다중 상속 시뮬레이션이 아닙니다. Java에서는 두 개의 클래스에서 상속 할 수 없지만 두 개의 인터페이스를 구현하면 두 개의 인터페이스 중 하나로 클래스를 사용할 수 있기 때문에 "두 개의 다른 클래스에서 상속 된 것처럼 보입니다".

예를 들면

interface MyFirstInteface{
    void method1();
}
interface MySecondInteface{
    void method2();
}
class MyClass implements MyFirstInteface, MySecondInteface{
    public void method1(){
        //Method 1
    }
    public void method2(){
        //Method 2
    }

    public static void main(String... args){
        MyFirstInterface mfi = new MyClass();
        MySecondInterface msi = new MyClass();
    }
}

이것은 작동하고 mfi 및 msi를 사용할 수 있습니다. 다중 상속처럼 보이지만 아무것도 상속하지 않기 때문이 아니라 인터페이스에서 제공하는 공용 메서드를 다시 작성합니다.


정확해야합니다.

Java는 인터페이스의 다중 상속을 허용하지만 구현의 단일 상속 만 허용합니다.

다음과 같이 Java에서 인터페이스의 다중 상속을 수행합니다.

public interface Foo
{
    String getX(); 
}

public interface Bar
{
    String getY();
}

public class MultipleInterfaces implements Foo, Bar
{
    private Foo foo;
    private Bar bar;

    public MultipleInterfaces(Foo foo, Bar bar)
    {
        this.foo = foo;
        this.bar = bar;
    }

    public String getX() { return this.foo.getX(); }
    public String getY() { return this.bar.getY(); }
}

그런데 Java가 완전한 다중 상속을 구현하지 않는 이유는 모호함을 만들기 때문입니다. "A가 B, C를 확장합니다"라고 말하면 B와 C 모두 "void f (int)"함수가 있다고 가정합니다. A는 어떤 구현을 상속합니까? Java의 접근 방식을 사용하면 여러 인터페이스를 구현할 수 있지만 인터페이스는 서명 만 선언합니다. 따라서 두 인터페이스에 동일한 시그니처가있는 함수가 포함되어 있으면 클래스가 해당 시그니처로 함수를 구현해야합니다. 상속하는 인터페이스에 서명이 다른 함수가있는 경우 함수는 서로 관련이 없으므로 충돌의 여지가 없습니다.

이것이 유일한 방법이라고 말하는 것이 아닙니다. C ++는 구현이이기는 우선 순위 규칙을 설정하여 진정한 다중 상속을 구현합니다. 그러나 Java 작성자는 모호성을 제거하기로 결정했습니다. 이것이 더 깨끗한 코드를 만들었다는 철학적 믿음 때문이든, 그들이 모든 추가 작업을하고 싶지 않았기 때문이든, 나는 잘 모르겠습니다.


인터페이스가 다중 상속을 '시뮬레이션'한다고 말하는 것은 불공평합니다.

물론, 당신의 타입은 여러 인터페이스를 구현할 수 있고 다형 적으로 다양한 타입으로 작동 할 수 있습니다. 그러나 분명히이 배열에 따라 동작이나 구현을 상속하지 않을 것입니다.

일반적으로 다중 상속이 필요할 수 있다고 생각하는 구성을 살펴보십시오.

또는 같은 것을 다중 상속을 달성하기위한 잠재적 인 해결책은 믹스 인 인터페이스입니다 - http://csis.pace.edu/~bergin/patterns/multipleinheritance.html . 주의해서 사용하십시오!


그렇지 않습니다.

인터페이스를 구현하는 것이 어떤 형태의 상속을 구성한다고 믿는 사람들이 혼란스러워한다고 생각합니다. 그렇지 않습니다. 구현은 단순히 공백 일 수 있으며 행위에 의해 강제되거나 계약을 통해 보장되지 않습니다. 전형적인 예는 Clonable 인터페이스입니다. 이것은 많은 훌륭한 기능을 암시하지만 본질적으로 쓸모없고 잠재적으로 위험 할 수있는 정의가 너무 적습니다.

인터페이스를 구현하여 무엇을 상속합니까? 버크스! 그래서 제 생각에는 같은 문장에서 인터페이스와 상속이라는 단어 사용을 중단하십시오. Michael Borgwardt가 말했듯이 인터페이스는 정의가 아니라 측면입니다.


인터페이스 자체를 구현하는 경우 여러 구체적인 클래스에서 실제로 "상속"할 수 있습니다. innerclasses이를 달성하는 데 도움이됩니다.

interface IBird {
    public void layEgg();
}

interface IMammal {
    public void giveMilk();
}

class Bird implements IBird{
    public void layEgg() {
        System.out.println("Laying eggs...");
    }
}

class Mammal implements IMammal {
    public void giveMilk() {
        System.out.println("Giving milk...");
    }
}

class Platypus implements IMammal, IBird {

    private class LayingEggAnimal extends Bird {}
    private class GivingMilkAnimal extends Mammal {}

    private LayingEggAnimal layingEggAnimal = new LayingEggAnimal();

    private GivingMilkAnimal givingMilkAnimal = new GivingMilkAnimal();

    @Override
    public void layEgg() {
        layingEggAnimal.layEgg();
    }

    @Override
    public void giveMilk() {
        givingMilkAnimal.giveMilk();
    }

}


많은 구현을 쉽게 상속 할 수있는 C ++에서 비롯된 저를 뒤에서 물고있는 것을 지적하고 싶습니다.

많은 메서드가 포함 된 "와이드"인터페이스가 있다는 것은 구체적인 클래스에서 많은 메서드를 구현해야하며 구현 간에 이러한 메서드를 쉽게 공유 할 수 없음 을 의미합니다.

예를 들면 :

interface Herbivore {
    void munch(Vegetable v);
};

interface Carnivore {
    void devour(Prey p);
}

interface AllEater : public Herbivore, Carnivore { };

class Fox implements AllEater {
   ... 
};

class Bear implements AllEater {
   ...
};

In this example, Fox and Bear cannot share a common base implementation for both it's interface methods munch and devour.

If the base implementations look like this, we'd maybe want to use them for Fox and Bear:

class ForestHerbivore implements Herbivore
    void munch(Vegetable v) { ... }
};

class ForestCarnivore implements Carnivore
    void devour(Prey p) { ... }
};

But we can't inherit both of these. The base implementations need to be member variables in the class and methods defined can forward to that. I.e:

class Fox implements AllEater {
    private ForestHerbivore m_herbivore;
    private ForestCarnivore m_carnivore;

    void munch(Vegetable v) { m_herbivore.munch(v); }
    void devour(Prey p) { m_carnivore.devour(p); }
}

This gets unwieldy if interfaces grow (i.e. more than 5-10 methods...)

A better approach is to define an interface as an aggregation of interfaces:

interface AllEater {
    Herbivore asHerbivore();
    Carnivore asCarnivore();
}

This means that Fox and Bear only has to implement these two methods, and the interfaces and base classes can grow independetly of the aggregate AllEater interface that concerns the implementing classes.

Less coupling this way, if it works for your app.


I don't think they do.

Inheritance is specifically an implementation-oriented relationship between implementations. Interfaces do not provide any implementation information at all, but instead define a type. To have inheritance, you need to specifically inherit some behaviors or attributes from a parent class.

I believe there is a question here somewhere specifically about the role of interfaces and multiple inheritance, but I can't find it now...


There's really no simulation of multiple inheritance in Java.

People will sometimes say that you can simulate multiple inheritance using Interfaces because you can implement more than one interface per class, and then use composition (rather than inheritance) in your class to achieve the behaviors of the multiple classes that you were trying to inherit from to begin with.


If it makes sense in your object model, you can of course inherit from one class and implement 1 or more interfaces as well.


There are cases where multiple-inheritance turns to be very handy and difficult to replace with interfaces without writing more code. For example, there are Android apps that use classes derived from Activity and others from FragmentActivity in the same app. If you have a particular feature you want to share in a common class, in Java you will have to duplicate code instead of let child classes of Activity and FragmentsActivity derive from the same SharedFeature class. And the poor implementation of generics in Java doesn't help either because writing the following is illegal:

public class SharedFeature<T> extends <T extends Activity>

...
...

There is no support for multiple inheritance in java.

This story of supporting multiple inheritance using interface is what we developers cooked up. Interface gives flexibility than concrete classes and we have option to implement multiple interface using single class. This is by agreement we are adhering to two blueprints to create a class.

This is trying to get closer to multiple inheritance. What we do is implement multiple interface, here we are not extending (inheriting) anything. The implementing class is the one that is going to add the properties and behavior. It is not getting the implementation free from the parent classes. I would simply say, there is no support for multiple inheritance in java.


No, Java does not support multiple inheritance. Neither using class nor using interface. Refer to this link for more info https://devsuyed.wordpress.com/2016/07/21/does-java-support-multiple-inheritance


I also have to say that Java doesn't support multiple inheritance.

You have to differentiate the meaning between extends and implements keywords in Java. If we use extends, we are actually inheriting the class after that keyword. But, in order to make everything simple, we can't use extends more than once. But you can implement as many Interfaces as you wish.

If you implement an interface, there's a zero chance that you will miss the implementation of all the methods in each interface (Exception: default implementations of interface methods introduced in Java 8) So, you are now fully aware of what is happening with the things that you have embedded to your fresh class.

Why Java doesn't allow multiple inheritance is actually, multiple inheritance makes the code somewhat complex. Sometimes, two methods of parent classes might conflict due to having the same signatures. But if you are forced to implement all the methods manually, you will get the full understanding about what's going on, as I mentioned above. It makes your code more understandable to you.

If you need more info on Java interfaces, check out this article, http://www.geek-programmer.com/introduction-to-java-interfaces/

참고URL : https://stackoverflow.com/questions/3556652/how-do-java-interfaces-simulate-multiple-inheritance

반응형