자바 내부 류 의 가시 성 을 탐구 하 다

전재 하 다
http://zhangjunhd.blog.51cto.com/113473/65624/
자바 에 서 는 내부 클래스 의 대상 을 만 들 때 이 대상 은 외부 클래스 를 만 드 는 this 와 연결 되 어 있 기 때문에 이 내부 클래스 대상 은 외부 클래스 의 모든 구성원 을 방문 할 수 있 습 니 다.private 구성원 을 포함 합 니 다.
한편,이 내부 대상 은 다른 유형의 대상 에 대한 방문 은 일반적인 접근 권한 문법 에 따라 특별한 지원 이 없다.여기 서 연구 해 야 할 것 은 외부 류 와 다른 유형의 대상 이 특정한 내부 대상,즉 내부 류 의 가시 적 인 문 제 를 어떻게 방문 할 수 있 는 지 하 는 것 이다.
다음은 예제 프로그램 Out.자바 입 니 다.그 중에서 4 개의 서로 다른 접근 권한 을 가 진 내부 클래스(private,default,proctected,Public)를 포함 하고 각 내부 클래스 에 각각 4 개의 서로 다른 접근 권한 을 가 진 구성원 과 방법 을 포함 합 니 다.외부 클래스 Out 에서 내부 클래스 인 스 턴 스 를 얻 는 방법 을 제공 합 니 다.

package com.zj.main;

public class Out {
    public PrivateIn getPrivateIn(){
       return new PrivateIn();
    }    

    public DefaultIn getDefaultIn(){
       return new DefaultIn();
    }    

    public ProtectedIn getProtectedIn(){
       return new ProtectedIn();
    } 

    public PublicIn getPublicIn(){
       return new PublicIn();
    }    

    private class PrivateIn implements InMethod{
       private int private_arg;
       int default_arg;
       protected int protected_arg;
       public int public_arg;       

       private void private_method(){};
       void default_method(){};
       protected void protected_method(){};
       public void public_method(){};
    }

    class DefaultIn implements InMethod{
       private int private_arg;
       int default_arg;
       protected int protected_arg;
       public int public_arg;   

       private void private_method(){};
       void default_method(){};
       protected void protected_method(){};
       public void public_method(){};
    }    

    protected class ProtectedIn implements InMethod{
       private int private_arg;
       int default_arg;
       protected int protected_arg;
       public int public_arg;      

       private void private_method(){};
       void default_method(){};
       protected void protected_method(){};
       public void public_method(){};

    }

    public class PublicIn implements InMethod{
       private int private_arg;
       int default_arg;
       protected int protected_arg;
       public int public_arg;

       private void private_method(){};
       void default_method(){};
       protected void protected_method(){};
       public void public_method(){};
    }

    public static void main(String[] args){
       //create an outer object
       Out out=new Out();       

       //create a private inner object by 'new'
       Out.PrivateIn privateIn=out.new PrivateIn();
       privateIn.private_arg=0;
       privateIn.private_method();

       // create a private inner object  by 'out's method'
       Out.PrivateIn privateIn2 = out.getPrivateIn();
       privateIn2.private_arg = 0;
       privateIn2.private_method();
    }
}

모든 4 개의 내부 클래스 는 하나의 인터페이스 인 Method 를 실현 하 였 으 며,이 인터페이스의 역할 은 다음 글 에서 토론 할 것 이다.내부 클래스 가 있 는 외부 클래스 가 내부 클래스 대상 에 대한 접근 권한 문 제 를 먼저 논의 하 겠 습 니 다.
1.외부 클래스 의 접근
우 리 는 두 가지 방식 으로 내부 클래스 의 인 스 턴 스 를 만 들 려 고 한다.
방식 1 OuterClassName.InnerClassName inner=new Ouer().new Inner();
외부 클래스 대상.new 방식 을 통 해 private inner class 의 인 스 턴 스 를 얻 을 수 있 으 며,private 구성원 과 private 방법 에 접근 할 수 있 습 니 다.자연 default,proctected,Public 모두 접근 할 수 있 습 니 다.
방식 2 외부 클래스 를 통 해 get InnerInstance()
이 방법 은 모든 내부 클래스 의 모든 구성원 과 방법 을 방문 할 수 있다.
따라서 내부 클래스 의 대상 은 그 를 생 성 하 는 외부 클래스 대상 에 대해 완전히 볼 수 있다.이 는 private 내부 클래스,private 구성원 과 private 방법 을 포함한다.
2.패키지 와 다른 종류의 접근
다음은 같은 가방 에 Same Package.java 클래스 를 만 들 고 Out 클래스 의 모든 내부 클래스 에 접근 하려 고 합 니 다.

package com.zj.main;

public class SamePackage {
    public static void main(String[] args) {
       // create an outer object
       Out out = new Out();

       //create a private inner object by 'new'
       //Out.PrivateIn privateIn=out.new PrivateIn();
       //->error: Out.PrivateIn is not visible.

       // create a default inner object by 'new'
       Out.DefaultIn defaultIn = out.new DefaultIn();
       //defaultIn.private_arg=0;->error:not visible

       defaultIn.default_arg = 0;

       //defaultIn.private_method();->error:not visible
       defaultIn.default_method();

       // create a private inner object by 'out's method'

       //Out.PrivateIn privateIn2 = out.getPrivateIn();
       //->error:Out.PrivateIn is not visible through out.getPrivateIn() is visible.

       // create a private inner object by 'out's method',
       // but use Interface reference to handle it
       InMethod privateIn=out.getPrivateIn();
       privateIn.public_method();
    }
}

방식 1 OuterClassName.InnerClassName inner=new Ouer().new Inner();
사용 방식 이 private 내부 클래스 를 얻 으 려 고 시도 하면 내부 클래스 의 핸들 을 얻 을 수 없습니다.
//create a private inner object by 'new'
//Out.PrivateIn privateIn=out.new PrivateIn();
//->error: Out.PrivateIn is not visible.
    그러나 default 접근 권한 의 내부 클래스 에 정상적으로 접근 할 수 있 는 대상 입 니 다.당연히 프 라이 빗 멤버 와 프 라이 빗 방법 을 방문 할 수 없습니다.자연 proctected 와 Public 는 모두 방문 할 수 있 습 니 다.
방식 2 외부 클래스 를 통 해 get InnerInstance()
외부 클래스 대상 의 getInnerInstance()방법 을 호출 할 수 있 지만 private 내부 클래스 의 핸들 을 얻 지 못 하기 때문에 이 방법 은 private 내부 클래스 의 인 스 턴 스 를 만 들 수 없습니다.
// create a private inner object by 'out's method'
//Out.PrivateIn privateIn2 = out.getPrivateIn();
//->error:Out.PrivateIn is not visible through out.getPrivateIn() is visible.
그러나 모든 내부 클래스 가 인터페이스 InMethod 를 실현 하기 때문이다.

public interface InMethod {
    void public_method();
}

그래서 인터페이스의 인용 을 통 해 private 내부 류 의 Public 방법 에 접근 할 수 있 습 니 다.자연 default,proctected,Public 는 모두 이 Public 방법 에 접근 할 수 있 습 니 다.
// create a private inner object by 'out's method',
// but use Interface reference to handle it
InMethod privateIn=out.getPrivateIn();
privateIn.public_method();
3.패키지 별 다른 종류의 접근
다른 가방 에 DifferPackage.java 클래스 를 만 듭 니 다.

package com.zj.other;

import com.zj.main.InMethod;
import com.zj.main.Out;

public class DifferPackage {
    public static void main(String[] args){
       //create an outer object
       Out out=new Out();

       //create a public inner object by 'new'
       Out.PublicIn publicIn=out.new PublicIn();
       publicIn.public_arg=0;
       publicIn.public_method();

       // create a public inner object by 'out's method'
       Out.PublicIn publicIn2 = out.getPublicIn();
       publicIn2.public_arg=0;
       publicIn2.public_method();

       //use Interface reference
       InMethod method;
       method=out.getPrivateIn();
       method.public_method();
       method=out.getDefaultIn();
       method.public_method();
       method=out.getProtectedIn();
       method.public_method();
       method=out.getPublicIn();
       method.public_method();
    }
}

new 방식 과 getInnerInstance()방법 을 통 해 Public 내부 류 의 Public 구성원 과 Public 방법 만 방문 할 수 있 습 니 다.인터페이스의 인용 을 사용 하면 4 개의 내부 클래스 의 Public 방법 을 모두 방문 할 수 있 습 니 다.
[b]4.서로 다른 패키지 계승 클래스 의 접근[\b]
다른 가방 에 DifferPackage Extend.java 를 만 들 고 외부 클래스 Out 에서 계승 합 니 다.

package com.zj.other;

import com.zj.main.Out;

public class DifferPackageAndExtend extends Out{
    public static void main(String[] args){
       //create an DifferPackageAndExtend's object,which extends Out
       Out extend=new DifferPackageAndExtend();

       //create a protected inner object by 'new'
       //Out.ProtectedIn protectedIn=extend.new ProtectedIn();
       //->error:The constructor Out.ProtectedIn() is not visible

       // create a protected inner object by 'out's method'
       Out.ProtectedIn protectedIn=extend.getProtectedIn();
       protectedIn.public_arg=0;
       protectedIn.public_method();
    }
}

new 방식 을 통 해 내부 클래스 의 문형 Out.Protected In 을 얻 을 수 있 지만 이 내부 클래스 의 구 조 는 보이 지 않 습 니 다.
getInnerInstance()방법 을 통 해 proctected 내부 클래스 의 대상 을 받 지만 Public 구성원 과 Public 방법 에 만 접근 할 수 있 습 니 다.이 를 통 해 알 수 있 듯 이 proctected 내부 류 는 다른 종류의 외부 류 를 계승 하 는 지 에 관심 이 없다.모든 proctected 접근 권한 은 이 경우 에 적용 되 지 않 습 니 다.

좋은 웹페이지 즐겨찾기