자바 내부 클래스 작용에 대한 깊이 있는 분석

6999 단어 java내부 클래스
자바 내부 클래스(Inner Class)를 언급하면 많은 사람들이 잘 알지 못할 수도 있다. 실제로 유사한 개념은 C++에도 있다. 바로 플러그인 클래스(Nested Class)이다. 이 두 가지의 차이와 관계에 대해 다음과 같이 비교할 수 있다.내부류는 표면적으로 보면 클래스에서 하나의 클래스를 정의한 것이다(아래에서 볼 수 있듯이 내부류는 많은 곳에서 정의할 수 있다). 실제적으로 그렇게 간단하지 않다. 언뜻 보면 내부는 약간 쓸데없는 것과 유사하다. 그 용도는 초보자에게 그렇게 현저하지 않을 수도 있지만 그것에 대해 깊이 있게 이해하면서 자바의 디자이너가 내부류에 있어서 확실히 애를 쓰는 것을 발견할 수 있다.내부 클래스를 사용하는 것을 습득하는 것은 자바 고급 프로그래밍의 일부분으로 프로그램 구조를 더욱 우아하게 설계할 수 있다.첫 만남

public interface Contents {
 int value();
}
public interface Destination {
 String readLabel();
}
public class Goods {
 private class Content implements Contents {
  private int i = 11;
  public int value() {
   return i;
  }
 }
 protected class GDestination implements Destination {
  private String label;
  private GDestination(String whereTo) {
   label = whereTo;
  }
  public String readLabel() {
   return label;
  }
 }
 public Destination dest(String s) {
  return new GDestination(s);
 }
 public Contents cont() {
  return new Content();
 }
}
class TestGoods {
 public static void main(String[] args) {
  Goods p = new Goods();
  Contents c = p.cont();
  Destination d = p.dest("Beijing");
 }
}
이 예에서 클래스 콘텐츠와 GDestination은 클래스 Goods 내부에 정의되고 각각protected와private 수식자를 가지고 접근 단계를 제어한다.콘텐츠는 Goods의 내용을 대표하고 GDestination은 Goods의 목적지를 대표한다.그것들은 각각 두 개의 인터페이스 Content와 Destination을 실현했다.뒤에 있는main 방법에서 Contents c와 Destination d로 직접 조작하면 이 두 내부 클래스의 이름도 볼 수 없습니다!이렇게 하면 내부류의 첫 번째 장점은 당신이 다른 사람에게 알리고 싶지 않은 조작, 즉 봉장성을 숨기는 것을 나타낸다.이 동시에 우리는 외부 클래스의 작용 범위 밖에서 내부 클래스의 대상을 얻는 첫 번째 방법을 발견했다. 그것이 바로 외부 클래스의 방법을 이용하여 창설하고 되돌아오는 것이다.상례의cont()와dest() 방법은 이렇게 하는 것입니다.그럼 다른 방법은 없을까요?물론 있습니다. 그 문법 형식은 다음과 같습니다. outerObject=new outerClass(Constructor Parameters).outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters); 비정적 내부 클래스 대상을 만들 때 반드시 상응하는 외부 클래스 대상을 먼저 만들어야 한다는 것을 주의하십시오.그 원인에 대해 말하자면 우리의 다음 화제는 비정적 내부 유형의 대상이 그 외부 유형의 대상을 가리키는 인용을 가지고 아까 예시를 약간 수정했다

public class Goods {
 private int valueRate = 2;
 private class Content implements Contents {
  private int i = 11 * valueRate;
  public int value() {
   return i;
  }
 }
 protected class GDestination implements Destination {
  private String label;
  private GDestination(String whereTo) {
   label = whereTo;
  }
  public String readLabel() {
   return label;
  }
 }
 public Destination dest(String s) {
  return new GDestination(s);
 }
 public Contents cont() {
  return new Content();
 }
}
여기서 우리는 Goods 클래스에private 구성원 변수valueRate를 추가했다. 의미는 화물의 가치 계수이고 내부 클래스content의 방법value()가 가치를 계산할 때 그것을 곱한다.우리는value()가valueRate에 접근할 수 있다는 것을 발견했다. 이것은 내부 클래스의 두 번째 장점이다. 내부 클래스 대상은 외부 클래스를 만드는 내용에 접근할 수 있고 심지어는 개인 변수까지 포함한다.이것은 매우 유용한 특성으로 우리가 디자인할 때 더욱 많은 사고방식과 지름길을 제공하였다.이 기능을 실현하려면 내부 클래스 대상은 반드시 외부 클래스 대상을 가리키는 인용이 있어야 한다.자바 컴파일러는 내부 클래스 대상을 만들 때 외부 클래스 대상의 인용도 은밀하게 전달하고 저장합니다.이렇게 하면 내부 클래스 대상이 항상 외부 클래스 대상에 접근할 수 있고 외부 클래스의 작용 범위 밖에서 내부 클래스 대상을 만들려면 반드시 외부 클래스 대상을 먼저 만들어야 하는 이유이기도 하다.내부 클래스의 한 구성원 변수가 외부 클래스의 한 구성원 변수와 동명이면 외부 클래스의 동명 구성원 변수가 차단되면 어떻게 합니까?괜찮습니다. 자바에서는 외부 클래스의 인용을 다음과 같은 형식으로 표현합니다. outerClass.this가 생기면 우리는 이런 차단 상황을 두려워하지 않을 것이다.정적 내부류는 일반적인 류와 마찬가지로 내부류도 정적일 수 있다.그러나 비정적 내부 클래스와 비교하면 정적 내부 클래스가 외부를 가리키는 인용이 없다는 데 차이가 있다.이것은 실제적으로 C++의 플러그인 클래스와 매우 비슷하다. 자바 내부 클래스와 C++ 플러그인 클래스의 가장 큰 차이는 외부를 가리키는 인용이 있는지에 있다. 물론 디자인의 측면과 그 세부 사항으로 볼 때 차이가 있다.그 밖에 어떠한 비정적 내부 클래스에서도 정적 데이터, 정적 방법 또는 또 하나의 정적 내부 클래스(내부 클래스의 끼워넣기는 한 층이 아닐 수 있다)가 있을 수 없다.하지만 정적 내부 클래스에서는 이 모든 것을 가질 수 있다.이것도 양자의 두 번째 차이라고 할 수 있겠지.부분 내부 클래스는 그렇습니다. Java 내부 클래스도 부분적일 수 있습니다. 이것은 하나의 방법, 심지어 코드 블록 안에 정의할 수 있습니다

public class Goods1 {
 public Destination dest(String s) {
  class GDestination implements Destination {
   private String label;
   private GDestination(String whereTo) {
    label = whereTo;
   }
   public String readLabel() {
    return label;
   }
  }
  return new GDestination(s);
 }
 public static void main(String[] args) {
  Goods1 g = new Goods1();
  Destination d = g.dest("Beijing");
 }
}
위에 바로 이런 예가 있다.방법dest에서 우리는 내부 클래스를 정의했고 마지막으로 이 방법으로 이 내부 클래스의 대상을 되돌려줍니다.만약 우리가 내부 클래스를 사용할 때 그것의 대상을 만들고 외부에 창조하기만 하면 이렇게 할 수 있다.물론 방법에 정의된 내부류는 디자인을 다양화할 수 있고 용도는 이 점에 그치지 않는다.다음은 더 이상한 예가 하나 있다

public class Goods2 {
 private void internalTracking(boolean b) {
  if (b) {
   class TrackingSlip {
    private String id;
    TrackingSlip(String s) {
     id = s;
    }
    String getSlip() {
     return id;
    }
   }
   TrackingSlip ts = new TrackingSlip("slip");
   String s = ts.getSlip();
  }
 }
 public void track() {
  internalTracking(true);
 }
 public static void main(String[] args) {
  Goods2 g = new Goods2();
  g.track();
 }
}
이 내부 클래스의 대상을 if 외에 만들 수 없습니다. 왜냐하면 이것은 이미 그 작용역을 초과했기 때문입니다.그러나 컴파일할 때 내부 클래스 Tracking Slip은 다른 클래스와 마찬가지로 동시에 컴파일됩니다. 단지 그 자체의 작용 영역에 의해 이 범위를 초과하면 무효입니다. 그 외에 다른 내부 클래스와 차이가 없습니다.익명 내부 클래스java의 익명 내부 클래스의 문법 규칙은 보기에는 좀 이상하지만, 익명 수조와 같이, 하나의 클래스의 대상을 만들고 그 이름을 사용할 수 없을 때, 내부 클래스를 사용하면 코드를 간결하고 명확하게 보일 수 있다.그것의 문법 규칙은 다음과 같다. new interfacename () {...};또는 new superclassname () {...};다음은 이어서 앞에서 계속 예를 들자

public class Goods3 {
 public Contents cont() {
  return new Contents() {
   private int i = 11;
   public int value() {
    return i;
   }
  };
 }
}
이 방법cont()는 익명 내부 클래스를 사용하여 인터페이스 Contents를 실현한 클래스의 대상을 직접 되돌려줍니다. 보기에 매우 간결합니다.자바의 이벤트 처리 익명 어댑터에서 익명 내부 클래스가 대량으로 사용됩니다.예를 들어 창을 닫으려면 다음과 같은 코드를 추가합니다

frame.addWindowListener(new WindowAdapter(){
 public void windowClosing(WindowEvent e){
    System.exit(0);
 }
});
주의해야 할 것은 익명 내부 클래스는 이름이 없기 때문에 구조 함수가 없다는 것이다. (그러나 이 익명 내부 클래스가 파라미터만 있는 구조 함수를 포함하는 부류를 계승한다면 이를 만들 때 반드시 이 파라미터를 가지고 실현되는 과정에서 슈퍼 키워드를 사용하여 해당하는 내용을 호출해야 한다.)구성원 변수를 초기화하려면 다음과 같은 몇 가지 방법이 있습니다. 만약 한 방법의 익명 내부 클래스라면, 이 방법을 이용하여 원하는 매개 변수를 전달할 수 있지만, 이 매개 변수는final로 성명되어야 한다는 것을 기억하십시오.익명 내부 클래스를 이름이 있는 국부 내부 클래스로 바꾸면 구조 함수를 가질 수 있다.이 익명 내부 클래스에서 초기화 코드 블록을 사용합니다.왜 내부 클래스가 필요합니까?java 내부 클래스는 어떤 장점이 있습니까?왜 내부 클래스가 필요합니까?먼저 간단한 예를 들어 만약에 당신이 인터페이스를 실현하고 싶지만 이 인터페이스의 한 방법은 당신이 구상한 이 종류의 한 방법의 명칭과 파라미터가 같으면 어떻게 해야 합니까?이때 너는 내부 클래스를 만들어서 이 인터페이스를 실현할 수 있다.내부 클래스는 외부 클래스의 모든 내용에 접근할 수 있기 때문에 이렇게 하면 당신이 직접 이 인터페이스를 실현하는 모든 기능을 완성할 수 있습니다.하지만 의문을 제기해야 할 것 같아. 방법을 바꾸면 되지 않겠어?확실히 이를 디자인 내부류로 삼는 이유는 설득력이 없다.진정한 원인은 이렇다. 자바의 내부 클래스와 인터페이스를 합치면 C++ 프로그래머들이 자바에 존재하는 문제가 많이 계승되지 않는다고 불평하는 것을 해결할 수 있다.실제로 C++의 다중 계승 디자인은 매우 복잡하지만 자바는 내부 클래스에 인터페이스를 추가하여 다중 계승 효과를 잘 실현할 수 있다.

좋은 웹페이지 즐겨찾기