it-swarm.com.de

Erben Unterklassen private Felder?

Dies ist eine Interviewfrage.

Erben Unterklassen private Felder?

Ich habe mit "Nein" geantwortet, weil wir nicht auf die "normale OOP Weise" zugreifen können. Der Interviewer glaubt jedoch, dass sie vererbt werden, weil wir auf solche Felder indirekt zugreifen können oder Reflexion und Sie sind noch im Objekt vorhanden.

Nachdem ich zurückgekommen war, fand ich das folgende Zitat im javadoc :

Private Mitglieder in einer Superklasse

Eine Unterklasse erbt nicht die privaten Mitglieder ihrer Elternklasse.

Kennen Sie Argumente für die Meinung des Interviewers?

227
Stan Kurilin

Die meisten Unklarheiten in den Fragen/Antworten betreffen die Definition von Vererbung.

Wie @DigitalRoss erklärt, muss natürlich ein [~ # ~] Objekt [~ # ~] einer Unterklasse die privaten Felder der Oberklasse enthalten. Wie er sagt, bedeutet kein Zugang zu einem privaten Mitglied, dass es nicht da ist.

Jedoch. Dies ist anders als der Begriff der Vererbung für eine Klasse. Wie in der Welt von Java), in der es um Semantik geht, ist der Arbiter Java Language Specification (derzeit 3. Ausgabe).

Wie das JLS angibt ( https://docs.Oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2 ):

Als privat deklarierte Klassenmitglieder werden nicht von Unterklassen dieser Klasse geerbt. Nur Mitglieder einer Klasse, die als geschützt oder öffentlich deklariert sind, werden von Unterklassen geerbt, die in einem anderen Paket deklariert sind als dem, in dem die Klasse deklariert ist.

Damit wird die genaue Frage des Interviewers beantwortet: "do sub [~ # ~] classes [~ # ~] erben private Felder". (Hervorhebung von mir hinzugefügt)

Die Antwort lautet Nein. OBJEKTE von Unterklassen enthalten private Felder ihrer Superklassen. Die Unterklasse selbst hat KEINE Ahnung von privaten Feldern ihrer Oberklasse.

Ist es eine pedantische Semantik? Ja. Ist es eine nützliche Interviewfrage? Wahrscheinlich nicht. Aber das JLS legt die Definition für die Java) Welt fest und tut dies (in diesem Fall) eindeutig.

BEARBEITET (entfernt ein paralleles Zitat von Bjarne Stroustrup, das aufgrund der Unterschiede zwischen Java und c ++ wahrscheinlich nur zur Verwirrung beiträgt. Ich lasse meine Antwort auf dem JLS ruhen :)

224
robert_x44

Ja

Es ist wichtig zu wissen, dass es zwar are zwei Klassen gibt, aber nur ein Objekt.

Also, ja, natürlich hat es die privaten Felder geerbt. Sie sind vermutlich für die ordnungsgemäße Objektfunktionalität wesentlich, und während ein Objekt der übergeordneten Klasse kein Objekt der abgeleiteten Klasse ist, ist eine Instanz der abgeleiteten Klasse meistens definitiv eine Instanz der übergeordneten Klasse. Es könnte nicht gut sein, dass ohne alle Felder.

Nein, Sie können nicht direkt darauf zugreifen. Ja, sie werden geerbt. Sie müssen sein.

Das ist eine gute Frage!


pdate:

Äh, "Nein"

Nun, ich denke, wir haben alle etwas gelernt. Da das JLS den genauen "nicht vererbten" Wortlaut hervorbrachte, ist es richtig, auf "nein" zu antworten. Da die Unterklasse nicht auf die privaten Felder zugreifen oder diese ändern kann, werden sie mit anderen Worten nicht vererbt. Aber es gibt wirklich ist ​​nur ein Objekt, es enthält wirklich die privaten Felder, und wenn jemand den JLS- und Tutorial-Text falsch formuliert Es wird ziemlich schwierig sein, OOP, Java Objekte und das, was wirklich passiert, zu verstehen.

pdate zum Update:

Die Kontroverse beinhaltet hier eine fundamentale Mehrdeutigkeit: was genau wird diskutiert? Das Objekt? Oder sprechen wir in gewissem Sinne über die Klasse selbst? Bei der Beschreibung der Klasse im Gegensatz zum Objekt ist viel Spielraum zulässig. Die Unterklasse erbt also keine privaten Felder, aber ein Objekt, das eine Instanz der Unterklasse ist , enthält mit Sicherheit enthält ​​die privaten Felder.

73
DigitalRoss

Nein. Private Felder werden nicht vererbt. Deshalb wurde Protected erfunden. Es ist beabsichtigt. Ich denke, dies hat die Existenz eines geschützten Modifikators gerechtfertigt.


Kommen wir nun zu den Zusammenhängen. Was ist mit geerbt gemeint - wenn es in dem Objekt vorhanden ist, das aus einer abgeleiteten Klasse erstellt wurde? ja ist es.

Wenn Sie meinen, kann es sinnvoll sein, Klasse abzuleiten. Nun, nein.

Wenn Sie nun zur funktionalen Programmierung kommen das private Feld der Superklasse wird für die Unterklasse nicht sinnvoll vererbt. Für die Unterklasse ist ein privates Feld der Superklasse dasselbe wie ein privates Feld einer anderen Klasse.

Funktionell ist es nicht vererbt. Aber im Idealfall ist es.


OK, habe gerade in Java Tutorial sie zitieren dies:

Private Mitglieder in einer Superklasse

Eine Unterklasse erbt nicht die privaten Mitglieder ihrer Elternklasse. Verfügt die Oberklasse jedoch über öffentliche oder geschützte Methoden für den Zugriff auf ihre privaten Felder, können diese auch von der Unterklasse verwendet werden.

siehe: http://download.Oracle.com/javase/tutorial/Java/IandI/subclasses.html

Ich bin damit einverstanden, dass das Feld da ist. Die Unterklasse erhält jedoch keine Berechtigung für dieses private Feld. Für eine Unterklasse ist das private Feld dasselbe wie jedes private Feld einer anderen Klasse.

Ich glaube, es ist nur eine Frage der Sichtweise. Sie können das Argument auf beiden Seiten formulieren. Es ist besser, beides zu rechtfertigen.

18
Nishant

Dies hängt von Ihrer Definition von "erben" ab. Hat die Unterklasse noch die Felder im Speicher? Bestimmt. Kann es direkt auf sie zugreifen? Nein, es sind nur Feinheiten der Definition. es geht darum zu verstehen, was wirklich passiert.

11
Mehrdad

Ich werde das Konzept mit Code demonstrieren. Unterklassen WIRKLICH erben die privaten Variablen der Superklasse. Das einzige Problem ist, dass sie nicht für die untergeordneten Objekte zugänglich sind, es sei denn, Sie geben öffentliche Getter und Setter für die privaten Variablen in der Superklasse an.

Betrachten Sie zwei Klassen im Paket Dump. Kind erweitert Elternteil.

Wenn ich mich richtig erinnere, besteht ein untergeordnetes Objekt im Speicher aus zwei Bereichen. Einer ist nur der Elternteil und der andere ist nur der Kindteil. Ein Kind kann auf den privaten Bereich im Code seines Elternteils nur über eine öffentliche Methode im Elternteil zugreifen.

Denk darüber so. Borats Vater Boltok hat einen Safe mit 100.000 US-Dollar. Er möchte seinen "privaten" Tresor nicht mit anderen teilen. Daher stellt er keinen Schlüssel für den Safe zur Verfügung. Borat erbt den Safe. Aber was nützt es, wenn er es nicht einmal öffnen kann? Wenn nur sein Vater den Schlüssel zur Verfügung gestellt hätte.

Eltern -

package Dump;

public class Parent {

    private String reallyHidden;
    private String notReallyHidden;

    public String getNotReallyHidden() {
        return notReallyHidden;
    }

    public void setNotReallyHidden(String notReallyHidden) {
        this.notReallyHidden = notReallyHidden;
    }

}//Parent

Kind -

package Dump;

public class Child extends Parent {

    private String childOnly;

    public String getChildOnly() {
        return childOnly;
    }

    public void setChildOnly(String childOnly) {
        this.childOnly = childOnly;
    }

    public static void main(String [] args){

        System.out.println("Testing...");
        Child c1 = new Child();
        c1.setChildOnly("childOnly");
        c1.setNotReallyHidden("notReallyHidden");

        //Attempting to access parent's reallyHidden
            c1.reallyHidden;//Does not even compile

    }//main

}//Child
10
Borat Sagdiyev

Nein, sie erben es nicht.

Die Tatsache, dass es von einer anderen Klasse indirekt verwendet wird, sagt nichts über die Vererbung aus, sondern über die Kapselung.

Zum Beispiel:

class Some { 
   private int count; 
   public void increment() { 
      count++;
   }
   public String toString() { 
       return Integer.toString( count );
   }
}

class UseIt { 
    void useIt() { 
        Some s = new Some();
        s.increment();
        s.increment();
        s.increment();
        int v = Integer.parseInt( s.toString() );
        // hey, can you say you inherit it?
     }
}

Sie können den Wert von count auch über Reflektion in UseIt abrufen. Es bedeutet nicht, dass Sie es erben.

[~ # ~] Update [~ # ~]

Obwohl der Wert vorhanden ist, wird er nicht von der Unterklasse geerbt.

Zum Beispiel eine Unterklasse definiert als:

class SomeOther extends Some { 
    private int count = 1000;
    @Override
    public void increment() { 
        super.increment();
        count *= 10000;
    }
}

class UseIt { 
    public static void main( String ... args ) { 
        s = new SomeOther();
        s.increment();
        s.increment();
        s.increment();
        v = Integer.parseInt( s.toString() );
        // what is the value of v?           
     }
}

Dies ist genau die gleiche Situation wie im ersten Beispiel. Das Attribut count ist ausgeblendet und überhaupt nicht von der Unterklasse geerbt. Dennoch, wie DigitalRoss betont, ist der Wert vorhanden, jedoch nicht durch Vererbung.

Sagen Sie es so. Wenn dein Vater reich ist und dir eine Kreditkarte gibt, kannst du immer noch etwas mit seinem Geld kaufen, aber das bedeutet nicht, dass du geerbt all das Geld, oder?

Anderes Update

Es ist jedoch sehr interessant, m zu wissen, warum das Attribut vorhanden ist.

Ich habe ehrlich gesagt nicht den genauen Begriff, um es zu beschreiben, aber es ist die JVM und die Art und Weise, wie sie funktioniert, die auch die übergeordnete Definition "nicht geerbt" lädt.

Wir könnten tatsächlich das übergeordnete Element ändern und die Unterklasse wird weiterhin funktionieren.

Zum Beispiel :

//A.Java
class A {
   private int i;
   public String toString() { return ""+ i; }
}
// B.Java
class B extends A {}
// Main.Java
class Main {
   public static void main( String [] args ) {
      System.out.println( new B().toString() );
    }
}
// Compile all the files
javac A.Java B.Java Main.Java
// Run Main
Java Main
// Outout is 0 as expected as B is using the A 'toString' definition
0

// Change A.Java
class A {
   public String toString() {
      return "Nothing here";
   }
}
// Recompile ONLY A.Java
javac A.Java
java Main
// B wasn't modified and yet it shows a different behaviour, this is not due to 
// inheritance but the way Java loads the class
Output: Nothing here

Der genaue Begriff könnte hier zu finden sein: The JavaTM Virtual Machine Specification

9
OscarRyz

Nun, meine Antwort auf die Frage des Interviewers lautet - Private Mitglieder werden nicht in Unterklassen vererbt, aber sie sind für Unterklassen oder Unterklassenobjekte nur über öffentliche Getter- oder Setter-Methoden oder über geeignete Methoden der ursprünglichen Klasse zugänglich. Die übliche Praxis besteht darin, die Mitglieder privat zu halten und mit öffentlichen Get- und Setter-Methoden auf sie zuzugreifen. Was bringt es also, nur Get- und Setter-Methoden zu erben, wenn das private Mitglied, mit dem sie sich befassen, für das Objekt nicht verfügbar ist? Hier bedeutet 'geerbt' einfach, dass es direkt in der Unterklasse verfügbar ist, um mit neu eingeführten Methoden in der Unterklasse herumzuspielen.

Speichern Sie die folgende Datei als ParentClass.Java und versuchen Sie es selbst ->

public class ParentClass {
  private int x;

  public int getX() {
    return x;
  }

  public void setX(int x) {
    this.x = x;
  }
}

class SubClass extends ParentClass {
  private int y;

  public int getY() {
    return y;
  }

  public void setY(int y) {
    this.y = y;
  }

  public void setXofParent(int x) {
    setX(x); 
  }
}

class Main {
  public static void main(String[] args) {
    SubClass s = new SubClass();
    s.setX(10);
    s.setY(12);
    System.out.println("X is :"+s.getX());
    System.out.println("Y is :"+s.getY());
    s.setXofParent(13);
    System.out.println("Now X is :"+s.getX());
  }
}

Output:
X is :10
Y is :12
Now X is :13

Wenn wir versuchen, die private Variable x von ParentClass in der Methode von SubClass zu verwenden, kann nicht direkt auf sie zugegriffen werden, um Änderungen vorzunehmen (dh nicht geerbt). X kann jedoch in SubClass über die setX () -Methode der ursprünglichen Klasse geändert werden, wie in der setXofParent () -Methode OR. Es kann mit dem ChildClass-Objekt über die setX () -Methode oder die setXofParent () -Methode geändert werden, die letztendlich setX () aufruft. . Also hier sind setX () und getX () eine Art Tor für das private Mitglied x einer ParentClass.

Ein weiteres einfaches Beispiel ist Clock-Superklasse, die Stunden und Minuten als private Mitglieder und geeignete Get- und Setter-Methoden als öffentliche Mitglieder hat. Dann kommt DigitalClock als Unterklasse von Clock. Wenn das Objekt der DigitalClock keine Mitglieder für Stunden und Minuten enthält, sind die Dinge durcheinander.

6
dganesh2002

Ok, das ist ein sehr interessantes Problem, das ich viel recherchiert habe und zu dem Schluss gekommen bin, dass private Mitglieder einer Oberklasse in den Objekten der Unterklasse tatsächlich verfügbar (aber nicht zugänglich) sind. Um dies zu beweisen, ist hier ein Beispielcode mit einer Elternklasse und einer Kindklasse. Ich schreibe ein Kindklassenobjekt in eine txt-Datei und lese ein privates Mitglied namens 'bhavesh' in der Datei, um zu beweisen, dass es tatsächlich im Kind vorhanden ist Klasse, aber aufgrund des Zugriffsmodifikators nicht zugänglich.

import Java.io.Serializable;
public class ParentClass implements Serializable {
public ParentClass() {

}

public int a=32131,b,c;

private int bhavesh=5555,rr,weq,refw;
}

import Java.io.*;
import Java.io.Serializable;
public class ChildClass extends ParentClass{
public ChildClass() {
super();
}

public static void main(String[] args) {
ChildClass childObj = new ChildClass();
ObjectOutputStream oos;
try {
        oos = new ObjectOutputStream(new FileOutputStream("C:\\MyData1.txt"));
        oos.writeObject(childObj); //Writing child class object and not parent class object
        System.out.println("Writing complete !");
    } catch (IOException e) {
    }


}
}

Öffnen Sie "MyData1.txt" und suchen Sie nach dem privaten Mitglied "bhavesh". Bitte lass mich wissen, was ihr denkt.

4
Bhavesh Agarwal

Es scheint, dass eine Unterklasse die privaten Felder erbt, indem genau diese Felder im Innenleben der Unterklasse verwendet werden (philosophisch gesprochen). Eine Unterklasse ruft in ihrem Konstruktor den Superklassenkonstruktor auf. Die privaten Felder der Oberklasse werden offensichtlich von der Unterklasse geerbt, die den Konstruktor der Oberklasse aufruft, wenn der Konstruktor der Oberklasse diese Felder in seinem Konstruktor initialisiert hat. Das ist nur ein Beispiel. Aber natürlich kann die Unterklasse ohne Zugriffsmethoden nicht auf die privaten Felder der Superklasse zugreifen (es ist, als ob Sie nicht in der Lage wären, die Rückseite eines iPhones zu öffnen, um den Akku herauszunehmen, um das Telefon zurückzusetzen ... aber der Akku ist immer noch da).

PS: Eine der vielen Definitionen der Vererbung, auf die ich gestoßen bin: "Vererbung - eine Programmiertechnik, mit der eine abgeleitete Klasse die Funktionalität einer Basisklasse erweitern kann, indem sie ihren gesamten Status (die Betonung liegt bei mir) und ihr Verhalten erbt."

Die privaten Felder, auch wenn sie für die Unterklasse nicht zugänglich sind, sind der geerbte Zustand der Oberklasse.

3
Flanker

Memory Layout in Java vis-a-vis inheritance

enter image description here

Füllbits/Ausrichtung und die Einbeziehung der Objektklasse in die VTABLE werden nicht berücksichtigt. Das Objekt der Unterklasse hat also einen Platz für die privaten Mitglieder der Superklasse. Es kann jedoch nicht von den Objekten der Unterklasse zugegriffen werden ...

Nein, private Felder werden nicht vererbt. Der einzige Grund ist, dass die Unterklasse nicht darauf zugreifen kann direkt.

1
joooohnli

Ich müsste darauf antworten, dass private Felder in Java are geerbt werden. Erlauben Sie mir zu demonstrieren:

public class Foo {

    private int x; // This is the private field.

    public Foo() {
        x = 0; // Sets int x to 0.
    }

    //The following methods are declared "final" so that they can't be overridden.
    public final void update() { x++; } // Increments x by 1.
    public final int getX() { return x; } // Returns the x value.

}


public class Bar extends Foo {

    public Bar() {

        super(); // Because this extends a class with a constructor, it is required to run before anything else.

        update(); //Runs the inherited update() method twice
        update();
        System.out.println(getX()); // Prints the inherited "x" int.

    }

}

Wenn Sie ein Programm Bar bar = new Bar(); ausführen, wird im Ausgabefeld immer die Zahl "2" angezeigt. Da die Ganzzahl "x" mit den Methoden update() und getX() gekapselt ist, kann nachgewiesen werden, dass die Ganzzahl vererbt ist.

Die Verwirrung ist, dass, weil Sie nicht direkt auf die Ganzzahl "x" zugreifen können, die Leute argumentieren, dass es nicht vererbt wird. Jedes nicht-statische Element in einer Klasse, sei es ein Feld oder eine Methode, wird jedoch vererbt.

0
Lawful Lazy

Auf einen Member oder Konstruktor einer privaten Klasse kann nur innerhalb des Hauptteils der Klasse der obersten Ebene ( §7.6 ) zugegriffen werden, der die Deklaration des Members oder Konstruktors enthält. Es wird nicht an Unterklassen vererbt. https://docs.Oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6

0
mimibar

Ich glaube, die Antwort hängt völlig von der gestellten Frage ab. Ich meine, wenn die Frage ist

Können wir direkt von ihrer Unterklasse aus auf das private Feld der Superklasse zugreifen?

Dann lautet die Antwort Nein , wenn wir durch das Zugangsdaten gehen, wird erwähnt, dass private Mitglieder nur innerhalb des zugänglich sind Klasse selbst.

Aber wenn die Frage ist

Können wir von ihrer Unterklasse aus auf das private Feld der Superklasse zugreifen?

Was bedeutet, es ist egal, was Sie tun, um auf das private Mitglied zuzugreifen. In diesem Fall können wir die Methode public in der Superklasse veröffentlichen und Sie können auf das private Mitglied zugreifen. In diesem Fall erstellen Sie also eine Schnittstelle/Bridge, um auf das private Mitglied zuzugreifen.

Andere OOPs-Sprachen wie C++ haben das friend function Konzept, mit dem wir auf das private Mitglied einer anderen Klasse zugreifen können.

0
Ravi

Wir können einfach sagen, dass, wenn eine Oberklasse geerbt wird, die privaten Mitglieder der Oberklasse tatsächlich private Mitglieder der Unterklasse werden und nicht weiter vererbt werden können oder für die Objekte der Unterklasse unzugänglich sind.

0
Aamir wani