ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • inner class
    Programming/JAVA 2020. 6. 28. 22:52

    내부 클래스

     

    한 클래스를 다른 클래스의 내부 클래스로 선언하면 두 클래스의 멤버들 간에 서로 쉽게 접근할 수 있는 장점이 있다.

    그리고 불필요한 클래스를 감춤으로써 코드의 복잡성을 줄일 수 있다.

    예를 들면 if {          //메서드 if {         //메서드            }/} ; 2중 if 문처럼 클래스도

     

    class A{

          class B{

                   ....

             }

    }

    여기서 클래스 A를 외부 클래스라고 하고 클래스 B를 내부 클래스라고 한다.

     

    변수의 종류처럼 지역변수, 인스턴스 변수, 인스턴스 변수 등 구분되어지는 거처럼 내부클래스도 종류별로 나눌 수 있다.

    내부 클래스 특징
    인스턴스 클래스 외부클래스의 멤버변수 선언위치에 선언.
    외부클래스의 객체들과 작업에 사용될 목적.
    스태틱 클래스 외부클래스의 멤버변수 선언위치에 선언.
    static 멤버, 특히 static 메서드에 사용 될 목적.
    지역 클래스 외부클래스의 메서드나 초기화 블럭 안에 선언, 그 영역에서만 사용할 수 있는 클래스.
    익명 클래스 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스
    class Outer{
    	private int iv=0;
        protected static int cv=0;
        
        void mymethod(){
        	int lv=0;
        }
    }
    class Outer{
    	private class InstanceInner{}
        protected static class StaticInner{}
        
        void myMethod(){
        	class LocalInner{}
        }
    }

    위 코드와 밑 코드는 변수의 종류들처럼 선언되는 위치에 따라서 클래스간의 규칙들이 똑같이 적용된다.

    내부클래스도 클래스이기 때문에 abstract 나 final 을 사용할 수 있고, private public protected등 사용이 가능하다.

    class innerclass{
    	class InstanceInner{
    		int iv=100;
    		//static int cv=100;STATIC 사용 불가(STATIC클래스만 STATIC 변수 선언)
    		final static int CONST = 100;//FINAL STATIC은 상수니까 허용
    	}
    	static class StaticInner{
    		int iv=200;
    		static int cv=200;//static 클래스니까 static 선언 가능
    	}
    	void myMethod() {
    		class LocalInner{
    			int iv=300;
    			//static int cv=300; static 사용 불가 에러
    			final static int CONST = 300;//FINAL STATIC은 상수니까 허용
    		}
    	}
    
    	public static void main(String[] args) {
    		System.out.println(InstanceInner.CONST);
    		System.out.println(StaticInner.cv);
    		}
    }
    

     

    위에처럼 static 클래스 내부에 static int cv=200; 처럼 static을 선언해도 되나 다른 클래스에서 보면 static클래스 선언을 안해주어서 static을 붙이는 것이 되지 않는다. 하지만 final static은 상수이므로 모든 내부클래스에서 정의가 가능하다.

    ->스태틱에는 스태틱 파이널 스태틱은 상수이니까 스태틱이 없는 다른 클래스에도 정의 가능.

     

    public class innerclass2 {
    	class InstanceInner{}
    	static class StaticInner{}
    	
    	InstanceInner iv=new InstanceInner(); //인스턴스멤버 간에는 서로 접근이 가능하다.
    	static StaticInner cv=new StaticInner();//스태틱멤버 간에는 서로 접근이 가능하다.
    	
    	static void staticMethod() {
    		//스태틱멤버는 인스턴스 멤버에 직접적으로 접근이 불가능하다.
    		//ex InstanceInner iv=new InstanceInner();
    		//굳이 접근하기위해서는
    		innerclass2 a=new innerclass2();
    		InstanceInner i=a.new InstanceInner();
    		//이런식으로 접근이 가능
    		StaticInner obj=new StaticInner();//스태틱멤버는 스태틱멤버에 접근가능
    	}
    	void intanceMethod() {
    		//인스턴스메서드에서는 인스턴스멤버와 static멤버 모두 접근이 가능하다.
    		//하지만 메서드내에 지역적으로 선언된 내부클래스는 외부에서 접근불가능하다.
    	}
    	void myMethod() {
    		class LocalInner{
    			LocalInner L=new LocalInner();//가능하지만
    		}
    	}
    	
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    	}
    
    }

    위 코드는 접근성을 나타낸다 InstancerInner이라는 인스턴스 클래스가 존재하며 StaticInner이라는 스태틱클래스가 존재한다.

     

    1. 인스턴스 구역에서 인스턴스클래스와 스태틱클래스 접근이 가능하다.

    2. 스태틱 클래스에서 스태틱멤버에는 접근이 가능하지만 인스턴스 클래스에 접근이 불가능하다.

     

    굳이 접근하기 위해서는 외부클래스의 객체를 만들어주고 외부클래스.new InstanceInner(); 이런식으로 접근한다.

    ->인스턴스 클래스는 외부 클래스의 인스턴스멤버를 객체생성없이 바로 사용가능하지만, 스태틱 클래스는 외부 클래스의 인스턴스멤버를 객체생성없이 사용할 수 없다.

    인스턴스 클래스는 스태틱 클래스의 멤버들을 객체생성없이 사용할 수 있지만, 스태틱 클래스에서는 인스턴스 클래스의 멤버들을 객체생성없이 사용할 수 없다. ->스태틱은 스태틱끼리만.

     

    하지만 저쪽 마지막 메서드인 mymethod에 있는 localInner클래스는 외부클래스의 인스턴스 메서드와 인스턴스 다 접근이 가능하다.(JDK 1.8)

    지역 클래스에서 나를 포함하는 메서드(외부 클래스)가 가지고 있는 지역변수를 쓸 수 있는데, 조건은 FIANL 이 붙어야한다. JDK 1.8부터 생략이 가능하지만 참조하더라도 해당 변수의 값이 바뀌게 되면 오류가 일어난다.

     

     

     

    class outer{
    	class InstanceInner{
    		int iv=100;
    	}
    	static class StaticInner{
    		int iv=200;
    		static int cv=300;
    	}
    	void myMethod() {
    		class LocalInner{
    			int iv=400;
    		}
    	}
    }
    
    class innerclass3{
    	public static void main(String[] args) {
    		//인스턴스클래스의 인스턴스를 생성하려면
    		//외부클래스의 인스턴스를 먼저 생성해야 한다.
    		outer oc=new outer();
    		outer.InstanceInner ii=oc.new InstanceInner();
    		System.out.println("ii.iv="+ii.iv);
    		System.out.println("Outer.StaticInner.cv="+outer.StaticInner.cv);
    		//스태틱 자체의 접근 스태틱 멤버로
    		outer.StaticInner si =new outer.StaticInner();
    		System.out.println("si.iv="+si.iv);
    	}
    }

    외워.......그냥.....이해안가...........지금 열두시.....나 자살......마려워......

    outer(클래스이름).내부클래스 ii = 객체이름.new 내부클래스이름()

    outer(클래스이름).내부클래스.ii=new outer(클래스이름).내부클래스이름()

     

    다른 클래스에서 참조할 때 객체 생성 꼭 해야하며

    같은 외부클래스에 있는 경우에는 내부클래스이름 객체이름 = 위에있던거 참조

    class outer{
    	int value=10;
    	class inner{
    		int value=20;
    		void method() {
    			int value=30;
    			System.out.println("value="+value);
    			System.out.println("innervalue="+this.value);
    			System.out.println("outervalue="+outer.this.value);
    		}
    	}
    }
    public class innerclass3 {
    	public static void main(String[] args) {
    		outer outer=new outer();
    		outer.inner inner=outer.new inner();
    		inner.method();
    	}
    }
    

     

    클래스에서 변수 이름이 같을 때 클래스명.this.변수이름

     

     

    익명클래스

     

    다른 클래스들과 달리 이름이 없는 클래스, 클래스의 선언과 객체생성을 동시에 하기 떄문에 단 한번만 사용이 가능하다.오직 단 하나만의 객체만을 생성할 수 있는 일회용 클래스

     

    일단 저장

     

    'Programming > JAVA' 카테고리의 다른 글

    [JAVA FX] Button 컨트롤  (0) 2020.11.04
    JAVA.LANG PACKAGE  (0) 2020.07.07
    abstract include interface(2)  (0) 2020.06.28
    abstract include interface  (0) 2020.06.27
    형변환(메모)  (0) 2020.06.16
Designed by Tistory.