Java >> Java tutorial >  >> Java

Hvorfor Java ikke understøtter Multiple Inheritance - Diamond Problem?

Multiple arv er intet andet end én klasse, der strækker sig over mere end én klasse. I JavaMultiple Arv understøttes ikke på grund af grunden til, at det vil være stille og roligt at administrere afhængighederne. Lad os se på det mest berømte problem kaldet “Diamond Problem“ hvilket opstår hvis Java understøttet Multiple Inheritance.

Multiple Inheritance i Java – Diamond Problem

I multipel nedarvning er der mange chancer for at have flere egenskaber eller flere metoder med det samme navn tilgængelige i forskellige underklasser, hvilket kan føre til tvetydighed. Lad os tage nedenstående eksempel på Java Multiple Inheritance

class A
{
    public void disp()
    {
        System.out.println("A disp() called");
    }
}
class B extends A
{
    @Override
    public void disp()
    {
        System.out.println("B disp() called");
    }
}
class C extends A
{
    @Override
    public void disp()
    {
        System.out.println("C disp() called");
    }
}
public class D extends B,C //Not Supported by Java
{
   public static void main(String args[])
   {
       D d = new D();
       d.disp(); // Ambiguity which disp() to call
   }
}
  • Klasse B og Klasse C arver Klasse A og disp() metode af Klasse A er tilsidesat af beggeB og C
  • Klasse D arver både Klasse B og C (Ikke understøttet af Java) , Hvis antag, at vi skal kalde disp() metode gennem forekomsten af ​​Klasse D , så vil Java-kompileren ikke vide, hvilken metode der skal kaldes om disp() metode for Klasse B eller Klasse C. Det resulterer i tvetydighed
  • For at overvinde ovenstående

Som i Java kan vi implementere mere end én java-grænseflade vi opnår den samme effekt ved at bruge grænseflader.

Flowdiagram

Begrebsmæssigt skal multipel arv være som nedenstående diagram, KlasseA   ogKlasseB begge arvet af ClassC . Da det ikke understøttes, vil vi ændre KlasseA til InterfaceA og Klasse B til InterfaceB .

Eksempel på multipel arv

Her har vi to grænseflader Bil og bus.

  • Bil grænsefladen har en attribut hastighed og en metode defineret distanceTravelled()
  • Bus grænsefladen har en attribut afstand og metode speed()

  Køretøjsklassen implementerer både grænsefladen Bil og Bus og giver implementering.

package com.javainterviewpoint.inheritance;

interface Car
{
    int  speed=60;
    public void distanceTravelled();
}
interface Bus
{
    int distance=100;
    public void speed();
}
public class Vehicle  implements Car,Bus
{
    int distanceTravelled;
    int averageSpeed;
    public void distanceTravelled()
    {
        distanceTravelled=speed*distance; 
        System.out.println("Total Distance Travelled is : "+distanceTravelled);
    }
    public void speed()
    {
        int averageSpeed=distanceTravelled/speed;
        System.out.println("Average Speed maintained is : "+averageSpeed);
    }
    public static void main(String args[])
    {
        Vehicle v1=new Vehicle();
        v1.distanceTravelled();
        v1.speed();
    }
}

Output:

Total Distance Travelled is : 6000
Average Speed maintained is : 100

I ovenstående kode har vi ikke tvetydighed, selv når vi bruger klasser i stedet for grænseflader , så kommer spørgsmålet hvorfor Java ikke understøtter ? . Problemet opstår, når begge klasser har den samme metode ? og compileren vil ikke vide, hvilken metode der skal kaldes, hvorimod grænsefladernes metoder som standard er abstrakte og implementeringer leveres ikke af grænsefladen, og derfor kan vi undgå tvetydigheden.

package com.javainterviewpoint.inheritance;

interface InterfaceA
{
    public void disp();
}
interface InterfaceB
{
    public void disp();
}
public class Client implements InterfaceA,InterfaceB
{
    @Override
    public void disp() 
    {
        System.out.println("disp() method implementation");
    }
    public static void main(String args[])
    {
        Client c = new Client();
        c.disp();
    }
}

Output:

disp() method implementation

Som vi kan se i ovenstående kode, er klientklassen har implementeret begge grænseflader InterfaceA og InterfaceB. I dette tilfælde gjorde vi ikke have tvetydighed selvom begge grænseflader har samme metode .


Java tag