Czy podklasy dziedziczą pola prywatne?

To jest pytanie o wywiad.

Czy podklasy dziedziczą prywatne pola?

Odpowiedziałem "Nie", ponieważ nie możemy uzyskać do nich dostępu za pomocą "normalnego sposobu OOP". Ale rozmówca uważa, że są one dziedziczone, ponieważ możemy uzyskać dostęp do takich pól pośrednio lub za pomocą odbicia i nadal istnieją w obiekcie.

Po powrocie znalazłem następujący cytat wjavadoc :

Private Members in a Superclass

A podklasa nie dziedziczy prywatnych członków swojej macierzystej klasy.

Czy znasz jakieś argumenty przemawiające za opinią rozmówcy?

Author: Peter O., 2011-01-17

17 answers

Większość zamieszania w pytaniach / odpowiedziach otacza definicję dziedziczenia.

Oczywiście, jak wyjaśnia @DigitalRoss, obiekt podklasy musi zawierać prywatne pola swojej superklasy. Jak twierdzi, brak dostępu do prywatnego członka nie oznacza, że go tam nie ma.

Jednak. Jest to inne niż pojęcie dziedziczenia dla klasy. Podobnie jak w świecie Javy, gdzie pojawia się kwestia semantyki, arbitrem jest Java Specyfikacja języka (obecnie wydanie 3).

Jak stwierdza JLS ( https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2):

Członkowie klasy, które są zadeklarowane prywatne nie są dziedziczone przez podklasy tej klasy. Tylko członkowie klasy, które są uznane za chronione lub publiczne są dziedziczone przez podklasy zadeklarowane w pakiecie innym niż taki, w którym deklarowana jest klasa.

To dotyczy dokładnie pytanie zadane przez rozmówcę: "do subCLASSES inherit private fields". (podkreślenie dodane przeze mnie)

Odpowiedź brzmi nie. Nie. Obiekty podklas zawierają prywatne pola swoich podklas. Sama podklasa nie ma pojęcia prywatnych pól swojej superklasy.

Czy to semantyka natury pedantycznej? Tak. Czy to przydatne pytanie podczas rozmowy kwalifikacyjnej? Pewnie nie. Ale JLS ustanawia definicję Świata Javy i tak się dzieje (w tym przypadku) / align = "left" /

EDITED (usunięto równoległy cytat z Bjarne Stroustrupa, który ze względu na różnice między Javą A c++ prawdopodobnie tylko dodać do zamieszania. Niech moja odpowiedź spocznie na JLS :)

 208
Author: robert_x44,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-11 12:01:04

Tak

Ważne jest, aby zdać sobie sprawę, że podczas gdy dwie klasy, istnieje tylko jeden obiekt.

Więc tak, oczywiście odziedziczył prywatne pola. Są one prawdopodobnie niezbędne do poprawnej funkcjonalności obiektu i podczas gdy obiekt klasy nadrzędnej nie jest obiektem klasy pochodnej, instancja klasy pochodnej jest w większości zdecydowanie instancją klasy nadrzędnej. Nie może być tak bez wszystkich pól. Nie, Nie możesz. bezpośredni dostęp do nich. Tak, są dziedziczone. Oni mają Być. To dobre pytanie!

Aktualizacja:

Err, " Nie "

Chyba wszyscy się czegoś nauczyliśmy. Ponieważ JLS wywodził dokładne sformułowanie "nie dziedziczone", poprawna jest Odpowiedź "NIE". Ponieważ podklasa nie może uzyskać dostępu ani modyfikować prywatnych pól, innymi słowy, nie są one dziedziczone. Ale tak naprawdę jest po prostu jeden obiekt, to naprawdę zawiera prywatne pola, więc jeśli ktoś źle potraktuje sformułowanie JLS i tutoriala, będzie dość trudno zrozumieć OOP, Obiekty Javy i to, co się naprawdę dzieje.

Update to update:

Kontrowersja tutaj wiąże się z fundamentalną dwuznacznością: o czym dokładnie się dyskutuje? obiekt?Czy mówimy w jakimś sensie o samej klasie? duża szerokość geograficzna jest dozwolona podczas opisywania klasy w przeciwieństwie do obiektu. Tak więc podklasa nie dziedziczy prywatnych pól, ale obiekt będący instancją podklasy z pewnością zawiera prywatne pola.

 67
Author: DigitalRoss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-07 19:04:52

Nie. Pola prywatne nie są dziedziczone... i dlatego wynaleziono Protected. Jest z założenia. To chyba uzasadniało istnienie chronionego modyfikatora.


Teraz do kontekstu. Co masz na myśli przez dziedziczenie -- jeśli jest tam w obiekcie utworzonym z klasy pochodnej? tak.

Jeśli masz na myśli, czy może być przydatna Klasa pochodna. Nie.

Teraz, kiedy przejdziesz do programowania funkcyjnego prywatne pole super klasy nie jest dziedziczone w znacząca droga dla podklasy . Dla podklasy, prywatne pole super klasy jest takie samo jak prywatne pole każdej innej klasy.

funkcjonalnie nie jest dziedziczona. Ale najlepiej , jest.


OK, po prostu zajrzałem do samouczka Javy cytują to:

Użytkownicy prywatni w Superklasie

Podklasa nie dziedziczy prywatnych członków swojej klasy macierzystej. Jeśli jednak Klasa nadrzędna ma metody publiczne lub chronione aby uzyskać dostęp do prywatnych pól, mogą one być również używane przez podklasę.

Zobacz: http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html

Zgadzam się, że pole tam jest. Ale podklasa nie ma żadnych przywilejów na tym prywatnym polu. W podklasie pole prywatne jest takie samo jak każde pole prywatne innej klasy.

uważam, że to kwestia punktu widzenia. Możesz uformować argument po obu stronach. It ' s better justify w obie strony.

 

 18
Author: Nishant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-27 09:53:47

To zależy od twojej definicji "dziedziczyć". Czy podklasa nadal ma pola w pamięci? Zdecydowanie. Czy ma do nich bezpośredni dostęp? Nie. Chodzi o to, żeby zrozumieć, co się naprawdę dzieje.

 10
Author: Mehrdad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-17 17:36:21

Zademonstruję tę koncepcję kodem. Podklasy faktycznie dziedziczą prywatne zmienne super klasy. Jedynym problemem jest to, że nie są one dostępne dla obiekty potomne, chyba że udostępnisz publiczne gettery i settery dla zmiennych prywatnych w super klasie.

Rozważmy dwie klasy w zrzucie pakietów. Dziecko rozszerza rodzica.

Jeśli dobrze pamiętam, obiekt potomny w pamięci składa się z dwóch regionów. Jedna jest tylko częścią nadrzędną, a druga to tylko część dziecięca. Dziecko ma dostęp do prywatnego sekcja w kodzie rodzica tylko za pomocą publicznej metody w rodzicu.

Pomyśl o tym w ten sposób. Ojciec Borata, Boltok, ma sejf zawierający 100 tysięcy dolarów. Nie chce udostępniać swojego" prywatnego " sejfu zmiennego. Więc nie dostarcza klucza do sejfu. Borat dziedziczy sejf. Ale co z tego, że nawet nie może go otworzyć ? Gdyby tylko jego Tata dostarczył klucz.

Rodzic -

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

Dziecko -

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
 9
Author: Borat Sagdiyev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-12 00:46:58

Nie. Nie odziedziczą go.

Fakt, że inna klasa może go używać pośrednio, nie mówi nic o dziedziczeniu, ale o enkapsulacji.

Na przykład:

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?
     }
}

Możesz również uzyskać wartość count wewnątrz UseIt poprzez odbicie. To nie znaczy, że dziedziczysz.

UPDATE

Mimo że wartość jest tam, nie jest dziedziczona przez podklasę.

Na przykład podklasa zdefiniowana jako:

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?           
     }
}

To jest dokładnie to samo sytuacja jako pierwszy przykład. Atrybut {[3] } jest ukryty i nie jest dziedziczony przez podklasę w ogóle. Mimo to, jak wskazuje DigitalRoss, wartość jest tam, ale nie w drodze dziedziczenia.

Ujmę to tak. Jeśli twój ojciec jest bogaty i daje Ci kartę kredytową, nadal możesz kupić coś za jego pieniądze, ale nie oznacza to, że masz dziedziczenie tyle pieniędzy, prawda?

Inne update

To jest bardzo interesujące, choć, aby wiedzieć, dlaczego atrybut tam jest.

Szczerze mówiąc nie mam dokładnego terminu, aby to opisać, ale to JVM i sposób, w jaki działa, ładuje również" nie dziedziczoną " definicję rodzica.

Możemy zmienić rodzica i podklasa nadal będzie działać.

Na przykład :

//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

Myślę, że dokładny termin można znaleźć tutaj: Specyfikacja maszyny Wirtualnej JavaTM

 9
Author: OscarRyz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:29

Cóż, moja odpowiedź na pytanie ankietera brzmi - prywatne członkowie nie są dziedziczone w podklasach, ale są dostępne dla podklasy lub obiektu podklasy tylko za pomocą publicznych metod getter lub setter lub dowolnych odpowiednich metod oryginalnej klasy. normalną praktyką jest zachowanie prywatności członków i dostęp do nich przy użyciu metod getter i setter, które są publiczne. Więc jaki jest sens dziedziczyć tylko metody getter i setter, gdy prywatny członek, z którym mają do czynienia, nie jest dostępne dla obiektu? Tutaj 'dziedziczenie' oznacza po prostu, że jest dostępne bezpośrednio w podklasie, aby bawić się nowo wprowadzonymi metodami w podklasie.

Zapisz poniższy plik jako ParentClass.java i spróbuj sam - >

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

Jeśli spróbujemy użyć prywatnej zmiennej x Klasy ParentClass w metodzie podklasy, to nie jest ona bezpośrednio dostępna dla żadnych modyfikacji (czyli nie dziedziczona). Ale x można modyfikować w podklasie za pomocą metody setX() oryginalnej klasy, tak jak to robi się w setXofParent() metoda lub może być modyfikowana przy użyciu obiektu klasy potomnej przy użyciu metody setX() lub metody setXofParent (), która ostatecznie wywołuje setX (). Tak więc setX () i getX() są rodzajami bram do prywatnego członka x Klasy ParentClass.

Innym prostym przykładem jest Clock superclass ma godziny i minuty jako członków prywatnych i odpowiednie metody getter i setter jako publiczne. Następnie jest DigitalClock jako podklasa zegara. Tutaj jeśli obiekt DigitalClock nie zawiera członków hours and mins, to rzeczy są nawaliło.

 5
Author: dganesh2002,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-04 04:39:15

Ok, jest to bardzo interesujący problem, który zbadałem i doszedłem do wniosku, że prywatni członkowie superklasy są rzeczywiście dostępni (ale niedostępni) w obiektach podklasy. Aby to udowodnić, oto przykładowy kod z klasą rodzica i klasą potomną i piszę obiekt klasy potomnej do pliku txt i czytam prywatnego członka o nazwie 'bhavesh' w pliku, udowadniając tym samym, że jest on rzeczywiście dostępny w klasie potomnej, ale nie jest dostępny ze względu na dostęp modyfikator.

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) {
    }


}
}

Otwórz MyData1.txt i wyszukaj prywatnego członka o imieniu 'bhavesh'. Dajcie mi znać, co myślicie.

 4
Author: Bhavesh Agarwal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-31 10:57:35

Wydaje się, że podklasa dziedziczy prywatne pola, ponieważ te właśnie pola są wykorzystywane w wewnętrznym działaniu podklasy (filozoficznie mówiąc). Podklasa w swoim konstruktorze nazywa konstruktor klasy superklasowej. Prywatne pola superclass są oczywiście dziedziczone przez podklasę wywołującą konstruktor superclass, jeśli konstruktor superclass zainicjował te pola w swoim konstruktorze. To tylko przykład. Ale oczywiście bez metod accessor podklasa nie może uzyskać dostępu do prywatnych pól klasy superclass (to tak, jakby nie móc otworzyć tylnego panelu iPhone ' a, aby wyjąć baterię, aby zresetować telefon... ale bateria nadal tam jest).

PS Jedna z wielu definicji dziedziczenia, z którą się zetknąłem: "Dziedziczenie - technika programowania, która pozwala klasie pochodnej rozszerzyć funkcjonalność klasy bazowej, dziedzicząc cały jej stan (nacisk jest mój) i zachowanie."

Pola prywatne, nawet jeśli nie dostępne przez podklasę, są dziedziczonym stanem klasy nadrzędnej.

 3
Author: Flanker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-04 03:00:58

Układ pamięci w Javie vis-a-vis dziedziczenie

Tutaj wpisz opis obrazka

Wypełnienie bitów/wyrównanie i włączenie klasy obiektu do VTABLE nie jest brane pod uwagę. Więc obiekt podklasy ma miejsce dla prywatnych członków Super klasy. Nie można jednak uzyskać do niego dostępu z obiektów podklasy...

 1
Author: somenath mukhopadhyay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-06 22:47:41

Uważam, że odpowiedź jest całkowicie zależna od pytania, które zostało zadane. Jeśli pytanie jest

Czy możemy bezpośrednio uzyskać dostęp do prywatnego pola super-klasy z ich podklasa ?

Wtedy odpowiedź brzmi No , jeśli przejdziemy przez szczegóły specyfikacji dostępu , to jest wspomniane, że członkowie prywatni są dostępni tylko wewnątrz samej klasy.

Ale jeśli pytanie jest

Czy możemy uzyskać dostęp do prywatnego pola super klasa z ich podklasa ?

Co oznacza, że nie ma znaczenia, co zrobisz, aby uzyskać dostęp do prywatnego członka. W takim przypadku możemy zrobić metodę publiczną w super-klasie i możesz uzyskać dostęp do prywatnego członka. Tak więc, w tym przypadku tworzysz jeden interfejs / most, aby uzyskać dostęp do prywatnego członka.

Inne języki OOPs jak C++, mają friend function koncepcja, dzięki której możemy uzyskać dostęp do prywatnego członka innej klasy.

 0
Author: Ravi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-30 12:53:32

Możemy po prostu stwierdzić, że gdy superklasa jest dziedziczona, to prywatne członkowie superklasy faktycznie stają się prywatnymi członkami podklasy i nie mogą być dalej dziedziczone lub są nieaktywne dla obiektów podklasy.

 0
Author: Aamir wani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-25 17:57:09

Musiałbym odpowiedzieć, że prywatne pola w Javie są dziedziczone. Pozwól, że zademonstruję:

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.

    }

}

Jeśli uruchomisz program Bar bar = new Bar();, zawsze zobaczysz liczbę " 2 " w polu wyjściowym. Ponieważ liczba całkowita " x " jest zamknięta za pomocą metod update() i getX(), można udowodnić, że liczba całkowita jest dziedziczona.

Zamieszanie polega na tym, że ponieważ nie możesz bezpośrednio uzyskać dostępu do liczby całkowitej "x", ludzie twierdzą, że nie jest ona dziedziczona. Jednak każdy nie statyczny rzecz w klasie, czy to pole czy metoda, jest dziedziczona.

 0
Author: Lawful Lazy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-26 23:39:50

Prywatny członek klasy lub konstruktor jest dostępny tylko w ciele klasy najwyższego poziomu (§7.6) w załączeniu deklaracja członka lub konstruktora. Nie jest dziedziczona przez podklasy. https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6

 0
Author: mimibar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-29 04:04:43

Nie , pola prywatne nie są dziedziczone. Jedynym powodem jest to, że podklasa nie może uzyskać do nich bezpośredniego dostępu .

 0
Author: joooohnli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-21 07:29:04

Podklasa nie dziedziczy prywatnych członków swojej klasy macierzystej. Jednakże, jeśli Klasa nadrzędna ma publiczne lub chronione metody dostępu do swoich prywatnych pól, mogą one być również używane przez podklasę.

 -1
Author: suprinder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-30 19:31:27

Członkowie prywatni (stan i zachowanie) są dziedziczone. Mogą one wpływać na zachowanie i rozmiar obiektu, który jest tworzony przez klasę. Nie wspominając już o tym, że są one bardzo dobrze widoczne dla podklas poprzez wszystkie dostępne mechanizmy łamania enkaptulacji lub mogą być zakładane przez ich implementatorów.

Chociaż dziedziczenie ma definicję "defacto", zdecydowanie nie ma związku z aspektami" widoczności", które są zakładane przez odpowiedzi" nie".

Więc nie ma trzeba być dyplomatycznym. JLS się myli.

Każde założenie, że nie są "dziedziczone", jest niebezpieczne i niebezpieczne.

Tak więc wśród dwóch (częściowo) sprzecznych definicji defacto (których Nie będę powtarzał), jedyną, która powinna być przestrzegana, jest ta, która jest bezpieczniejsza (lub bezpieczna).

 -2
Author: gkakas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-31 08:13:32