서브클래스는 개인 필드를 상속합니까?
인터뷰 질문입니다.
서브클래스는 개인 필드를 상속합니까?
"No"라고 대답한 이유는 "normal OOP way"로는 액세스할 수 없기 때문입니다.그러나 면접관은 간접적으로 또는 반성을 통해 이러한 필드에 접근할 수 있고, 여전히 객체 내에 존재하기 때문에 이러한 필드는 유전된다고 생각합니다.
다시 돌아와서 javadoc에서 다음 견적을 발견했습니다.
슈퍼클래스의 프라이빗멤버전
하위 클래스는 부모 클래스의 개인 멤버를 상속하지 않습니다.
면접관의 의견에 대해 아는 것이 있습니까?
이 질문/답변에서 혼란스러운 대부분은 상속의 정의를 둘러싸고 있습니다.
@DigitalRoss에서 설명한 바와 같이 서브클래스의 OBJECT에는 슈퍼클래스의 개인 필드가 포함되어 있어야 합니다.그가 말했듯이, 개인 회원과 접촉할 수 없다고 해서 거기에 없는 것은 아니다.
하지만.이것은 클래스의 상속 개념과는 다릅니다.의미론에 대한 의문이 있는 Java 세계의 경우와 마찬가지로 아비터는 Java Language Specification(현재 제3판)입니다.
JLS에 기재된 바와 같이(https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2):
비공개로 선언된 클래스의 멤버는 해당 클래스의 하위 클래스에 상속되지 않습니다.보호됨 또는 공용으로 선언된 클래스의 멤버만 클래스가 선언된 패키지가 아닌 다른 패키지로 선언된 하위 클래스에 상속됩니다.
이는 인터뷰 진행자가 제기한 "서브CLASS는 개인 필드를 상속합니까?"라는 질문에 대한 것입니다.(내가 추가한 파일)
대답은 '아니오'입니다.그들은 그렇지 않다.서브클래스의 오브젝트에는 슈퍼클래스의 프라이빗필드가 포함됩니다.서브클래스 자체에는 슈퍼클래스의 개인 필드에 대한 개념이 없습니다.
현학적 성격의 의미론인가요?네. 유용한 면접 질문인가요?아마 아닐 것입니다.그러나 JLS는 Java World에 대한 정의를 확립하고 (이 경우) 모호하지 않게 정의합니다.
EDITED (Java와 c++의 차이로 인해 Bjarne Strostrup에서 병렬 인용문을 삭제했습니다.)답변은 JLS에 맡기겠습니다.
네.
클래스는 2개이지만 오브젝트는 1개뿐이라는 것을 깨닫는 것이 중요합니다.
네, 물론 개인 필드를 물려받았죠.이들은 적절한 오브젝트 기능에 필수적이며 부모 클래스의 오브젝트는 파생 클래스의 오브젝트가 아니지만 파생 클래스의 인스턴스는 대부분 확실히 부모 클래스의 인스턴스입니다.모든 분야가 없다면 그렇게 될 수 없습니다.
아니요, 직접 액세스할 수 없습니다.네, 그들은 유전됩니다.그래야 해.
좋은 질문입니다!
업데이트:
에러, "아니오"
뭐, 우리 모두 뭔가를 배웠나 봐요JLS는 정확하게 "상속되지 않은" 표현을 사용했기 때문에 "아니오"라고 대답하는 것이 옳습니다.하위 클래스는 개인 필드에 액세스하거나 수정할 수 없으므로, 즉 개인 필드는 상속되지 않습니다.그러나 실제로는 1개의 오브젝트밖에 없습니다.개인 필드가 포함되어 있지 않기 때문에 JLS와 튜토리얼의 표현을 잘못 사용하면 OOP, Java 오브젝트 및 실제로 무슨 일이 일어나고 있는지 이해하기 어렵습니다.
업데이트 대상:
여기서의 논쟁은 근본적인 모호성을 수반한다: 정확히 무엇이 논의되고 있는가?그 물건이요?아니면 수업 자체에 대해 어떤 의미에서 얘기하는 건가요?객체가 아닌 클래스를 설명할 때는 많은 위도를 사용할 수 있습니다.따라서 하위 클래스는 개인 필드를 상속하지 않지만 하위 클래스의 인스턴스인 개체에는 개인 필드가 확실히 포함됩니다.
아니요. 개인 필드는 상속되지 않습니다...그래서 프로텍트가 발명된 거야그것은 고의로 만들어졌다.보호되는 수식어의 존재를 정당화했다고 생각합니다.
이제 문맥으로 넘어가겠습니다.상속된 클래스 - 파생 클래스에서 생성된 객체에 상속된 객체가 있는 경우?네, 그렇습니다.
파생된 클래스에 유용하게 쓰일 수 있다는 의미입니다.저, 아닙니다.
기능 프로그래밍에 관해서는 슈퍼클래스의 프라이빗 분야는 서브클래스에 대해 의미 있는 방식으로 계승되지 않습니다.서브클래스의 경우 슈퍼클래스의 프라이빗필드는 다른 클래스의 프라이빗필드와 동일합니다.
기능적으로는 유전되지 않습니다.하지만 이상적으로는 그렇습니다.
Java 튜토리얼을 보면 다음과 같습니다.
슈퍼클래스의 프라이빗멤버전
하위 클래스는 부모 클래스의 개인 멤버를 상속하지 않습니다.단, 슈퍼클래스에 프라이빗필드에 액세스하기 위한 퍼블릭메서드 또는 보호된 메서드가 있는 경우 서브클래스에서도 이러한 메서드를 사용할 수 있습니다.
참조: http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html
나도 동의해, 그 분야는 거기에 있어.단, 서브클래스는 그 프라이빗필드에 대한 특권을 얻지 않습니다.서브클래스에 대해 프라이빗필드는 다른 클래스의 프라이빗필드와 동일합니다.
순전히 관점의 문제라고 생각합니다.너는 어느 쪽이든 그 주장을 만들 수 있다.어느 쪽이든 정당화하는 게 좋을 거야.
"상속"의 정의에 따라 달라집니다.서브클래스에 아직 필드가 메모리에 저장되어 있습니까?물론입니다.직접 접근할 수 있나요?아니요. 단지 미묘한 정의일 뿐입니다. 중요한 것은 실제로 무슨 일이 일어나고 있는지를 이해하는 것입니다.
코드로 컨셉을 시연합니다.하위 클래스는 실제로 슈퍼 클래스의 개인 변수를 상속합니다.유일한 문제는 슈퍼 클래스의 개인 변수에 대해 퍼블릭게터 및 세터를 제공하지 않는 한 하위 개체에 액세스할 수 없다는 것입니다.
패키지 덤프 내의 두 가지 클래스를 고려합니다.자녀가 부모를 확장합니다.
내 기억이 맞다면 메모리 내의 자 객체는 두 개의 영역으로 구성되어 있습니다.하나는 상위 부분이고 다른 하나는 하위 부분입니다.자녀는 부모의 코드에 있는 개인 섹션에 부모의 공용 메서드를 통해서만 액세스할 수 있습니다.
이렇게 생각해 보세요.보라트의 아버지 볼톡은 10만 달러가 든 금고를 가지고 있다.그는 자신의 "개인" 변수 금고를 공유하고 싶지 않다.그래서 그는 금고 열쇠를 제공하지 않는다.보라트는 금고를 상속받는다.하지만, 그가 그것을 열 수도 없다면 무슨 소용이 있겠는가? 그의 아버지가 열쇠를 제공했다면 좋았을 텐데.
부모 -
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
에 inside inside inside 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
는 숨겨져 서브클래스에 전혀 상속되지 않습니다.그러나 Digital Ross가 지적한 바와 같이 상속에는 가치가 없지만 상속에는 가치가 없습니다.
이렇게 말하자.아버지가 부자여서 신용카드를 주신다고 해도 아버지 돈으로 물건을 살 수는 있지만, 그 돈을 모두 물려받은 것은 아니겠죠?
기타 업데이트
그 속성이 왜 거기에 있는지 아는 것은 매우 흥미롭습니다.
사실 정확한 용어는 없지만 JVM과 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 메서드만 상속하는 것은 어떤 의미가 있을까요?개인 멤버는 오브젝트에 사용할 수 없습니다.여기서 '상속'이란 단순히 서브클래스에서 새로 도입된 메서드를 사용하여 서브클래스에서 직접 사용할 수 있음을 의미합니다.
다음 파일을 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
SubClass 메서드에서 ParentClass의 개인 변수 x를 사용하려고 하면 수정(상속되지 않음)에 직접 액세스할 수 없습니다.단, x는 setXofParent() 메서드와 같이 원래 클래스의 setX() 메서드를 사용하여 SubClass에서 변경할 수 있습니다.또한 setX() 메서드 또는 setX() 메서드를 사용하여 ChildClass 개체를 사용하여 변경할 수 있습니다.이 메서드는 최종적으로 setX()를 호출합니다.여기서 setX()와 getX()는 ParentClass의 개인 멤버x에 대한 일종의 게이트입니다.
또 하나의 간단한 예로서 Clock superclass는 시간과 시간을 프라이빗멤버로 하고 적절한 getter 메서드와 setter 메서드를 public으로 합니다.다음으로 Digital Clock이 Clock의 서브클래스로 표시됩니다.여기서 Digital Clock 객체에 시간 및 최소 멤버가 포함되어 있지 않으면 모든 것이 엉망이 됩니다.
네, 이것은 제가 많이 연구한 매우 흥미로운 문제입니다.그리고 결론에 도달한 것은 슈퍼클래스의 프라이빗 멤버는 서브클래스의 오브젝트에서 실제로 사용할 수 있지만 액세스 할 수 없다는 것입니다.이를 증명하기 위해 여기에 부모 클래스와 자녀 클래스가 있는 샘플코드가 있습니다.자녀 클래스 오브젝트를 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를 입력하고 'txtavesh'라는 이름의 개인 멤버를 검색합니다.여러분들의 의견을 들려주세요.
서브클래스는 이러한 분야가 서브클래스의 내적 작용에 이용된다는 점에서 개인 분야를 계승하는 것으로 보인다(철학적으로 말한다).하위 클래스는 해당 생성자에서 슈퍼 클래스 생성자를 호출합니다.슈퍼클래스 컨스트럭터가 컨스트럭터에서 필드를 초기화한 경우 슈퍼클래스 개인 필드는 슈퍼클래스 컨스트럭터를 호출하는 서브클래스에 의해 상속됩니다.그건 그냥 예에 불과해요.그러나 물론 액세스 방법이 없으면 서브클래스는 슈퍼클래스의 개인 필드에 접근할 수 없습니다(아이폰의 후면 패널을 팝업하여 배터리를 분리하여 전화기를 리셋할 수 없는 것과 같습니다).배터리는 그대로입니다).
PS 상속의 많은 정의 중 하나: "상속 - 파생 클래스가 기본 클래스의 기능을 확장하고 모든 상태(강조성은 내 것이다)와 동작을 상속할 수 있도록 하는 프로그래밍 기술"
개인 필드는 하위 클래스에서 액세스할 수 없는 경우에도 슈퍼 클래스의 상속된 상태입니다.
예를들면,
class Person {
private String name;
public String getName () {
return this.name;
}
Person(String name) {
this.name = name;
}
}
public class Student extends Person {
Student(String name) {
super(name);
}
public String getStudentName() {
return this.getName(); // works
// "return this.name;" doesn't work, and the error is "The field Person.name is not visible"
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student("Bill");
String name = s.getName(); // works
// "String name = s.name;" doesn't work, and the error is "The field Person.name is not visible"
System.out.println(name);
}
}
비트/얼라인먼트 패딩 및 VTAB에 객체 클래스 포함LE는 고려되지 않습니다.따라서 하위 클래스의 개체에는 Super 클래스의 개인 구성원을 위한 공간이 있습니다.그러나 하위 클래스의 개체에서는 액세스할 수 없습니다.
Java의 개인 필드는 상속됩니다.예를 들어 보겠습니다.
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"에 직접 접근할 수 없기 때문에 사람들은 그것이 유전되지 않았다고 주장한다는 것입니다.단, 필드든 메서드든 클래스의 모든 비정적 것은 상속됩니다.
아니요, 개인 필드는 상속되지 않습니다.유일한 이유는 서브클래스가 직접 액세스할 수 없기 때문입니다.
제 생각에는, 대답은 전적으로 질문에 달려있습니다.내 말은, 만약 질문이
슈퍼클래스의 개인 필드에 서브클래스에서 직접 접근할 수 있습니까?
그러면 "아니오"가 됩니다.접근 지정자의 상세 내용을 살펴보면 프라이빗 멤버는 클래스 자체 내에서만 액세스할 수 있습니다.
근데 만약에 질문이
슈퍼클래스의 개인 필드에 서브클래스에서 접근할 수 있습니까?
즉, 개인 멤버에게 접근하기 위해 무엇을 할지는 중요하지 않습니다.이 경우 슈퍼클래스로 공개하고 개인 회원에 접속할 수 있습니다.따라서 이 경우 프라이빗멤버에 접속하기 위한 인터페이스/브릿지를 1개 만듭니다.
C++와 같은 다른 OOP 언어에는 다른 클래스의 개인 멤버에 액세스할 수 있는 개념이 있습니다.
단순히 슈퍼클래스가 상속되면 슈퍼클래스의 프라이빗멤버는 실제로 서브클래스의 프라이빗멤버가 되어 서브클래스의 오브젝트에 더 이상 상속할 수 없거나 도달할 수 없다고 말할 수 있습니다.
프라이빗 클래스 멤버 또는 컨스트럭터는 멤버 또는 컨스트럭터의 선언을 둘러싼 최상위 클래스( (7.6)의 본문 내에서만 액세스 할 수 있습니다.서브클래스에 상속되지 않습니다.https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6
하위 클래스는 부모 클래스의 개인 멤버를 상속하지 않습니다.단, 슈퍼클래스에 프라이빗필드에 액세스하기 위한 퍼블릭메서드 또는 보호된 메서드가 있는 경우 서브클래스에서도 이러한 메서드를 사용할 수 있습니다.
참조: https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html #:~:text=Private%20멤버%20in%20a%20슈퍼클래스, be%20used%20by%20the%20subclass.
내가 도와줄게.
서브클래스(예를 들어 이름 있는 B)가 슈퍼클래스(예를 들어 이름 있는 A)를 확장하면 슈퍼클래스로부터 필드(속성이나 메서드 등)를 자동으로 상속합니다.
메모리 레이아웃의 B에는 클래스 A의 모든 필드(프라이빗 필드도 포함)에 대한 공간이 있습니다.사실 Java는 하위 클래스 B가 개인 필드를 사용하는 것을 허용하지 않습니다. B는 개인 필드이기 때문입니다.
하위 클래스는 부모 클래스의 개인 멤버를 상속하지 않습니다.단, 슈퍼클래스에 프라이빗필드에 액세스하기 위한 퍼블릭메서드 또는 보호된 메서드가 있는 경우 서브클래스에서도 이러한 메서드를 사용할 수 있습니다.
프라이빗 멤버(상태 및 동작)는 상속됩니다.클래스에 의해 인스턴스화된 개체의 동작 및 크기에 영향을 줄 수 있습니다.서브클래스는 이용할 수 있거나 구현자가 상정할 수 있는 모든 캡슐화 해제 메커니즘을 통해 매우 잘 볼 수 있습니다.
상속은 "확실"한 정의를 가지고 있지만, "아니오"라는 대답에 의해 가정되는 "가시성" 측면과는 분명히 관련이 없습니다.
그러니 외교적으로 할 필요는 없다.이 시점에서 JLS는 단지 잘못되었다.
그들이 "상속되지" 않았다는 가정은 안전하지 않고 위험하다.
따라서 (부분적으로) 상충되는 두 가지 정의 중에서 따라야 할 것은 더 안전한 정의(또는 안전한 정의)뿐입니다.
언급URL : https://stackoverflow.com/questions/4716040/do-subclasses-inherit-private-fields
'programing' 카테고리의 다른 글
Maven 환경 변수 (0) | 2022.09.03 |
---|---|
왜 여기에 정수 리터럴을 넣어야 하는지 아세요? (0) | 2022.09.03 |
Vue.js : Vuex의 상태 속성 데이터는 얼마나 지속됩니까? (0) | 2022.08.29 |
Javescript는 어레이에서 요소를 자동으로 제거합니다. (0) | 2022.08.29 |
재사용 가능한 폼 Vue 구성 요소 생성 방법 (0) | 2022.08.29 |