서브 클래스는 개인 필드를 상속합니까? 없으므로 “아니오”라고 대답했습니다. 그러나 면접관은

이것은 인터뷰 질문입니다.

서브 클래스는 개인 필드를 상속합니까?

“일반 OOP 방식”을 사용하여 액세스 할 수 없으므로 “아니오”라고 대답했습니다. 그러나 면접관은 이러한 필드를 간접적으로 또는 리플렉션을 사용하여 액세스 할 수 있으며 여전히 객체에 존재하기 때문에 상속 된 것으로 생각합니다.

돌아온 후 javadoc 에서 다음 인용문을 찾았습니다 .

수퍼 클래스의 개인 회원

서브 클래스는 부모 클래스의 private 멤버를 상속하지 않습니다.

면접관의 의견에 대한 논쟁이 있습니까?



답변

여기에있는 질문 / 답변의 혼란은 대부분 상속의 정의를 둘러 쌉니다.

@DigitalRoss가 설명했듯이 서브 클래스 의 객체 는 반드시 슈퍼 클래스의 개인 필드를 포함해야합니다. 그가 말했듯이, 개인 회원에 대한 액세스 권한이 없다고해서 해당 회원이 없다는 것을 의미하지는 않습니다.

하나. 이것은 클래스의 상속 개념과 다릅니다. 시맨틱에 대한 의문이있는 Java 세계의 경우와 마찬가지로 중재자는 Java 언어 사양 (현재 3 판)입니다.

JLS가 명시한대로 ( https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2 ) :

private로 선언 된 클래스의 멤버는 해당 클래스의 서브 클래스에 의해 상속되지 않습니다. protected 또는 public으로 선언 된 클래스의 멤버 만 클래스가 선언 된 패키지가 아닌 패키지에 선언 된 서브 클래스에 의해 상속됩니다.

이것은 면접관이 제기 한 정확한 질문을 다룬다 : “하위 클래스는 개인 필드를 상속한다”. (나에 의해 추가 된 강조)

대답은 아니요입니다. 그렇지 않습니다. 서브 클래스의 오브젝트는 수퍼 클래스의 개인 필드를 포함합니다. 서브 클래스 자체에는 수퍼 클래스의 개인 필드가 없습니다.

그것은 pedantic 자연의 의미론인가? 예. 유용한 인터뷰 질문입니까? 아마 아닙니다. 그러나 JLS는 Java 세계에 대한 정의를 확립하며 (이 경우) 명확하게 수행합니다.

편집 (Bjarne Stroustrup에서 병렬 인용문을 제거했습니다 .Java와 c ++의 차이점으로 인해 혼란을 더할 수 있습니다. JLS에 대한 답변을 드리겠습니다 🙂


답변

그것은 거기있는 동안 것을 깨닫게하는 것이 중요 하다 두 개의 클래스를 하나의 객체가있다.

물론, 그것은 개인 필드를 물려 받았습니다. 그것들은 아마도 적절한 객체 기능에 필수적이며, 부모 클래스의 객체는 파생 클래스의 객체가 아니지만 파생 클래스의 인스턴스는 대부분 분명히 부모 클래스의 인스턴스입니다. 모든 분야가 없으면 그렇게 될 수 없었습니다.

아니요, 직접 액세스 할 수 없습니다. 예, 그들은 상속받습니다. 그들은 해야 합니다.

좋은 질문입니다!


최신 정보:

Err, “아니오”

글쎄, 우리 모두가 무언가를 배운 것 같아. JLS 는 정확한 “상속되지 않은”문구를 시작 했기 때문에 “no”라고 대답하는 것이 맞습니다 . 서브 클래스는 개인 필드에 액세스하거나 개인 필드를 수정할 수 없으므로 다시 말해 상속되지 않습니다. 그러나 실제로 하나의 객체 가 있으며 실제로 개인 필드를 포함 하므로 누군가가 JLS 및 자습서 문구를 잘못 입력하면 OOP, Java 객체 및 실제로 발생하는 상황을 이해하기가 매우 어려울 것입니다.

업데이트 업데이트 :

여기서 논란은 근본적인 모호성을 포함합니다. 정확히 무엇을 논의하고 있습니까? 객체? 아니면 수업 자체 에 대해 어떤 의미로 이야기 하고 있습니까? 객체와 반대로 클래스를 설명 할 때 많은 위도가 허용됩니다. 서브 클래스가 없습니다 상속 private 필드를 않지만, 그래서 서브 클래스의 인스턴스 인 객체는 확실하지 가 포함 전용 필드.


답변

아니요. 개인 필드는 상속되지 않습니다 . 이것이 바로 Protected 가 발명 이유 입니다. 의도적으로 설계된 것입니다. 이것이 protected modifier의 존재를 정당화했다고 생각합니다.


이제 상황에 왔습니다. 상속 된 의미-파생 클래스에서 만든 객체에 있다면? 그렇습니다.

당신이 의미하는 경우 파생 클래스에 유용 할 수 있습니다. 음 … 아니.

이제 함수형 프로그래밍을 할 때 수퍼 클래스의 전용 필드는 하위 클래스에 대해 의미있는 방식으로 상속되지 않습니다 . 서브 클래스의 경우, 수퍼 클래스의 개인 필드는 다른 클래스의 개인 필드와 동일합니다.

기능적으로는 상속되지 않습니다. 그러나 이상적으로그렇습니다 .


자, Java 자습서를 살펴보면 다음과 같이 인용합니다.

수퍼 클래스의 개인 회원

서브 클래스는 부모 클래스의 private 멤버를 상속하지 않습니다. 그러나 수퍼 클래스가 개인 필드에 액세스하기위한 공용 또는 보호 된 메소드를 가지고 있으면 서브 클래스에서도 사용할 수 있습니다.

보내다: 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내부 의 가치를 얻을 수도 있습니다 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 Virtual Machine Specification


답변

면접관의 질문에 대한 나의 대답은- 개인 멤버는 서브 클래스에서 상속되지 않지만 공개 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

SubClass의 메소드에서 ParentClass의 전용 변수 x를 사용하려고하면 수정을 위해 직접 액세스 할 수 없습니다 (상속되지 않음). 그러나 x는 setXofParent () 메소드에서와 같이 원래 클래스의 setX () 메소드를 통해 SubClass에서 수정 될 수 있습니다. 여기에서 setX ()와 getX ()는 ParentClass의 private 멤버 x에 대한 일종의 게이트입니다.

또 다른 간단한 예는 Clock 수퍼 클래스에 개인 구성원으로 시간과 분이 있고 공용으로 적절한 getter 및 setter 메소드가 있다는 것입니다. 그런 다음 DigitalClock이 Clock의 하위 클래스로 제공됩니다. 여기서 DigitalClock의 객체에 시간과 분이 포함되어 있지 않으면 문제가 해결됩니다.