Наследуют ли подклассы частные поля?
Это вопрос для интервью.
наследуют ли подклассы private поля?
Я ответил "Нет", потому что мы не можем получить к ним доступ, используя"обычный способ ООП". Но интервьюер думает, что они наследуются, потому что мы можем получить доступ к таким полям косвенно или с помощью отражения, и они все еще существуют в объекте.
после того, как я вернулся, я нашел следующую цитату в документация:
частная Члены суперкласса
A подкласс не наследует private члены родительского класса.
вы знаете какие-либо аргументы в пользу мнения интервьюера?
17 ответов:
большая часть путаницы в вопросе / ответах здесь окружает определение наследования.
очевидно, как @DigitalRoss объясняет объект подкласса должны содержать частные поля его суперкласса. Как он заявляет, отсутствие доступа к частному члену не означает, что его нет.
да
важно понимать, что пока есть are два класса, есть только один объект.
Так что, да, конечно, он унаследовал частные поля. Они, по-видимому, необходимы для правильной функциональности объекта, и хотя объект родительского класса не является объектом производного класса, экземпляр производного класса в основном определенно является экземпляром родительского класса. Это не может быть очень хорошо, что без всех поля.
нет, вы не можете получить к ним прямой доступ. Да, они наследуются. Они есть быть.
хороший вопрос!
обновление:
Err, "Нет"
JLS возникла точная" не унаследованная " формулировка, правильно ответить "нет". Поскольку подкласс не может получить доступ или изменить частные поля, тогда, другими словами, они не наследуются. Но там действительно - это просто один
нет. Частные поля не наследуются... и вот почему защищенный придумали. Это сделано специально. Я думаю, это оправдывает существование защищенного модификатора.
теперь перейдем к контекстам. Что вы подразумеваете под унаследованным -- если он есть в объекте, созданном из производного класса? да, это так.
Если вы имеете в виду это может быть полезно для производного класса. Ну, нет.
теперь, когда вы пришли к функциональному программированию частное поле суперкласс не наследуется значимым образом для подкласса. Для подкласса частное поле суперкласса совпадает с частным полем любого другого класса.
функционально, это не наследуется. Но удобно, это.
ок, просто посмотрел в Java учебник, они цитируют это:
частные члены в суперклассе
подкласс не наследует private члены родительского класса. Однако, если суперкласс имеет открытые или защищенные методы для доступа к своим частным полям, они также могут использоваться подклассом.
см.:http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html
Я согласен,что поле есть. Но подкласс не получает никаких привилегий в этом частном поле. Для подкласса частное поле такое же, как и любое частное поле любого другого класс.
Я считаю, что это исключительно вопрос точки зрения. Вы можете формировать аргумент с любой стороны. Это лучше оправдать в обоих направлениях.
Это зависит от вашего определения понятия "наследование". У подкласса все еще есть поля в памяти? Определенно. Может ли он получить к ним прямой доступ? Нет. Это просто тонкости определения; суть в том, чтобы понять, что происходит на самом деле.
я продемонстрирую концепцию с кодом. Подклассы на самом деле наследование частные переменные суперкласса. Единственная проблема заключается в том, что они не работает к дочерние объекты, если вы не предоставляете общедоступные геттеры и сеттеры для частных переменных в супер классе.
рассмотрим два класса в дамп пакета. Ребенок расширяет родителя.
Если я правильно помню, дочерний объект в памяти состоит из двух регионов. Один из них-это только родительская часть, а другая-только дочерняя часть. Ребенок может получить доступ к частной раздел в коде своего родителя только через открытый метод в родителе.
подумайте об этом таким образом. У отца Бората Болтока есть сейф с $ 100,000. Он не хочет делиться своей" частной " переменной safe. Таким образом, он не предоставляет ключ от сейфа. Борат наследует сейф. Но что толку, если он даже не может ее открыть ? Если бы только его папа обеспечил ключ.
родитель -
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
ребенка -
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
нет. Они его не наследуют.
тот факт, что какой-то другой класс может использовать его косвенно, ничего не говорит о наследовании, но об инкапсуляции.
например:
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? } }
вы также можете получить значение
count
внутриUseIt
через отражение. Это не значит, что вы наследуете его.обновление
даже если значение есть, оно не наследуется подклассом.
например, подкласс определяется как:
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? } }
это точно такая же ситуация, как в первом примере. Атрибут
count
- это скрытые и не наследуется подклассом вообще. Тем не менее, как указывает DigitalRoss, значение есть, но не с помощью наследования.положите его таким образом. Если ваш отец богат и дает вам кредитную карту, вы все еще можете купить вещь на его деньги, но это не значит, что у вас есть унаследовала все эти деньги, не это?
другое обновление
это очень интересно, однако,чтобы узнать, почему этот атрибут есть.
у меня, честно говоря, нет точного термина для его описания, но это JVM и способ его работы, который загружает также "не унаследованное" родительское определение.
мы могли бы фактически изменить родителя и подкласс будет по-прежнему работать.
//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
Я думаю точно термин можно найти здесь:Спецификация Виртуальной Машины JavaTM
Ну, мой ответ на вопрос интервьюера - частные члены не наследуются в подклассах, но они доступны для подкласса или объекта подкласса только через общедоступные методы getter или setter или любые такие соответствующие методы исходного класса. нормальная практика состоит в том, чтобы держать членов закрытыми и получать к ним доступ с помощью методов getter и setter, которые являются общедоступными. Так что только наследуя методы getter и setter, когда собственный член они не доступен ли объект? Здесь "унаследованный" просто означает, что он доступен непосредственно в подклассе, чтобы играть вокруг вновь введенных методов в подклассе.
сохраните приведенный ниже файл как ParentClass.Java и попробуйте сами ->
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
если мы попытаемся использовать частную переменную x родительского класса в методе подкласса, то она не будет напрямую доступна для каких-либо модификаций (т. е. не наследуется). Но x может быть изменен в подклассе с помощью метода setX () исходного класса, как это сделано в метод setXofParent () или его можно изменить с помощью объекта ChildClass с помощью метода setX () или метода setXofParent (), который в конечном итоге вызывает setX (). Итак, здесь setX() и getX () являются своего рода воротами к частному члену x родительского класса.
еще один простой пример-суперкласс часов имеет часы и минуты как частные члены и соответствующие методы getter и setter как публичные. Затем идет DigitalClock как подкласс часов. Здесь, если объект DigitalClock не содержит часов и минут члены тогда все испортили.
ок, это очень интересная проблема, которую я исследовал много и пришел к выводу, что частные члены суперкласса станут доступны (но не работает) в объекты подкласса. Чтобы доказать это, вот пример кода с родительским классом и дочерним классом, и я пишу объект дочернего класса в txt-файл и читаю частный член с именем "bhavesh" в файле, следовательно, доказывая, что он действительно доступен в дочернем классе, но недоступен из-за доступа модификатор.
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) { } } }
Открыть MyData1.txt и поиск частного члена по имени "Бхавеш". Пожалуйста, дайте мне знать, что вы думаете.
PS Одно из многих определений наследования, с которым я столкнулся: "Наследование-метод программирования, который позволяет производному классу расширять функциональность базового класса, наследуя все его состояние (акцент мой) и поведение."
частные поля, даже если подкласс недоступен, это наследуемое состояние суперкласса.
Я думаю, ответ полностью зависит от вопроса, который был задан. Я имею в виду, если вопрос
у нас можете напрямую доступ к закрытому полю супер-класс их суб-класс ?
тогда ответ нет, если мы пройдем через подробности спецификатора доступа, как уже упоминалось, частные члены доступны только внутри самого класса.
но, если вопрос это
можем ли мы получить доступ к закрытому полю суперкласса из их суб-класс ?
значит, это не имеет значения, что вы будете делать, чтобы получить доступ к закрытому члену. В этом случае мы можем сделать открытый метод в суперклассе, и вы можете получить доступ к частному члену. Таким образом, в этом случае вы создаете один интерфейс/мост для доступа к частному члену.
другой язык OOPs, такой как C++, имеет
friend function
концепция, по которой мы может получить доступ к закрытому члену класса.
мы можем просто заявить, что когда суперкласс наследуется, то частные члены суперкласса фактически становятся частными членами подкласса и не могут быть далее унаследованы или недоступны для объектов подкласса.
Я должен был бы ответить, что частные поля в Java are по наследству. Позвольте мне продемонстрировать:
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. } }
если вы работаете в программе
Bar bar = new Bar();
, то вы всегда будете видеть число " 2 " в поле вывода. Потому что целое число " x " инкапсулируется с помощью методовupdate()
иgetX()
, то можно доказать, что целое число наследуется.путаница заключается в том, что, поскольку вы не можете напрямую получить доступ к целому числу "x", то люди утверждают, что это не так унаследованный. Однако каждая нестатическая вещь в классе, будь то поле или метод, наследуется.
частный член класса или конструктор доступен только в теле класса верхнего уровня ( §7.6), который заключает в себе объявление члена или конструктора. Он не наследуется подклассами. https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6
нет частные поля не наследуются. Единственная причина в том, что подкласс не может получить к ним доступ напрямую.
подкласс не наследует закрытые члены своего родительского класса. Однако, если суперкласс имеет открытые или защищенные методы для доступа к своим частным полям, они также могут использоваться подклассом.
закрытые члены (состояние и поведение) наследуются. Они (могут) влиять на поведение и размер объекта, который создается классом. Не говоря уже о том, что они очень хорошо видны подклассам через все механизмы нарушения энкаптуляции, которые доступны или могут быть приняты их исполнителями.
хотя наследование имеет определение "defacto", оно определенно не имеет связи с аспектами "видимости", которые предполагаются "нет" ответы.
итак, нет необходимости быть дипломатичным. JLS просто ошибается на данный момент.
любое предположение, что они не "наследуются", небезопасно и опасно.
таким образом, среди двух дефакто (частично) конфликтующих определений (которые я не буду повторять), единственным, которому следует следовать, является более безопасное (или безопасное).