티스토리 뷰

1. 추상 클래스와 내부 클래스

1. abstract 예약어

  • 추상 메서드 : 메서드의 시그니쳐 (리턴타입, 메서드명, 매개변수만 정의)
    • 메서드의 기본적인 기능 유추 가능
  • 추상 클래스 : 일반적으로 하나 이상의 추상 메서드 포함, (추상 메서드 없는 추상 클래스 가능)
    • 추상 메서드를 포함하면 반드시 추상 클래스로 선언되어야 함
    • 추상 클래스는 객체 생성을 할 수 없다.

 

추상 클래스

  • 추상 클래스로 객체를 생성하려면, 자식 클래스를 작성하고, 추상 메서드들을 Overriding 해야 함
    • 유지보수 편의성
// TV 클래스를 추상 클래스로 정의한다.
abstract class TV {
    public abstract void powerOn();
    public abstract void powerOff();
    public abstract void volumeUp();
    public abstract void volumeDown();
}

// TV 클래스를 상속하여 S_TV 클래스 정의 => Overriding 필요
class S_TV extends TV {
    public void powerOn() {
        System.out.println("S_TV --- 전원을 켠다.");
    }
    public void powerOff() {
        System.out.println("S_TV --- 전원을 끈다.");
    }
    public void volumeUp() {
        System.out.println("S_TV --- 소리를 높인다.");
    }
    public void volumeDown() {
        System.out.println("S_TV --- 소리를 낮춘다.");
    }
}

//TV 클래스를 상속하여 L_TV 클래스 정의 => Overriding 필요
class L_TV extends TV {
    public void powerOn() {
        System.out.println("L_TV --- 전원을 켠다.");
    }
    public void powerOff() {
        System.out.println("L_TV --- 전원을 끈다.");
    }
    public void volumeUp() {
        System.out.println("L_TV --- 소리를 높인다.");
    }
    public void volumeDown() {
        System.out.println("L_TV --- 소리를 낮춘다.");
    }
}

public class AbstractTVUser {
    public static void main(String[] args) {
        S_TV tv = new S_TV();
//        L_TV tv = new L_TV();

        tv.powerOn();
        tv.powerOff();
        tv.volumeUp();
        tv.volumeDown();

//        S_TV --- 전원을 켠다.
//        S_TV --- 전원을 끈다.
//        S_TV --- 소리를 높인다.
//        S_TV --- 소리를 낮춘다.
    }
}

 

2. 내부 클래스

  • 클래스는 데이터를 표현하기 위한 하나의 기본 단위로, 멤버 변수와 메서드로 구성된다.

  • 클래스가 다른 클래스를 포함하는 경우, 내부에 포함된 클래스를 내부 클래스라고 한다.

    • 내부 클래스는 JDK 초기 버전부터 지원되었던 개념
    • 파일 크기의 최소화, 보안, 성능 향상, 이벤트 처리 등을 쉽게 하기 위하여 사용됨.
  • 내부 클래스는 정의되는 위치에 따라 멤버 클래스와 지역 클래스로 나뉜다.

멤버 클래스 지역 클래스
- 멤버 변수와 동일한 위치에 선언된 내부 클래스
- static 멤버, instance 멤버로 나뉜다.
- 동일한 클래스 뿐만 아니라 다른 클래스에서도 활용될 수 있다.
- 클래스의 멤버 변수와 성격이 비슷하다.
- 메서드 내에 클래스가 정의되어 있는 경우
- 지역 클래스 (이름을 갖고 있음) 와 무명 클래스 (이름을 갖지 않음)으로 나뉜다.
- 활용 범위가 메서드 블록 내부로 제한되는 등 지역 변수와 성격이 비슷하다.

 

instance 멤버 내부 클래스

  • instance 멤버 내부 클래스는 클래스의 멤버와 동일한 위치에서 선언되는 내부 클래스
  • 멤버 변수, 메서드와 동일 위치에서 선언되었기 때문에 다른 외부의 클래스에서도 사용 가능하다.
// 외부 클래스 (Top Level Class)
class Outside {
    // 내부 클래스 - 일반 멤버 변수와 동일 위치에 정의함
    public class Inside {
    }
}

public class InnerClassTest {
    public static void main(String args[]) {
        // 내부 클래스의 객체 생성을 위해 외부 클래스의 객체를 생성해야 함
        Outside outer = new Outside();
        Outside.Inside inner = outer.new Inside();
    }
}

// 컴파일
// Outside.class
// Outside$Inside.class

 

static 멤버 내부 클래스

  • 외부 클래스 객체를 생성하지 않고도 내부 클래스 객체를 생성할 수 있다.
// 외부 클래스 (Top Level Class)
class Outside {
    // Static 내부 클래스 
    public static class StaticInside {
    }
}

public class InnerClassTest {
    public static void main(String args[]) {
        // static 내부 클래스 객체 생성 - 외부 클래스 객체 생성하지 않아도 생성됨
        Outside.StaticInner sinner = new Outside.StaticInner();
    }
}

 

이름이 있는 지역 내부 클래스

  • 메서드 내부에서 정의된 클래스, 지역 변수와 동일한 범위를 가짐
  • 클래스의 이름이 명시되는 클래스다.
// 외부 클래스
class Animal {
 void performBehavior() {
     // 이름이 있는 지역 내부 클래스
     class Brain {
         // - 지역 내부 클래스를 정의함
         // - 지역 변수와 동일한 범위 -> 클래스가 선언된 메서드 블록 내에서만 사용 가능함
     }
 }
}

public class InnerClassTest {
 public static void main(String args[]) {
     Animal outer = new Animal();
//     Animal.Brain inner = outer.new Brain();
 }
}
// 컴파일
// Animal.class
// Animal$1Brain.class

 

이름이 없는 지역 내부 클래스

  • 이름을 갖지 않는 내부 클래스
  • new 예약어 뒤에 명시된 클래스가 기존의 클래스인 경우에는 자동적으로 이 클래스의 자식 클래스가 됨
  • 이름이 없기 때문에 무명의 내부 클래스라고도 함
  • 이름이 없는 지역 내부 클래스는 추상 클래스의 객체를 내부 클래스 형태로 생성할 때 자주 사용됨
  • 추상 클래스는 추상 메서드를 포함하고 있기 때문에 객체를 생성할 수 없음
    • 추상 클래스를 상속한 클래스가 만들어져 객체를 생성해야 함
    • 간단하게 이름이 없는 지역 내부 클래스로 만들어 사용하는 것이 편리할 수 있음
// 이름이 없는 지역 내부 클래스 구현

abstract class TV {
    public abstract void powerOn();
    public abstract void powerOff();
    public abstract void volumeUp();
    public abstract void volumeDown();
}

public class AnonymousTest {
    public static void watchTV(TV tv) {
        tv.powerOn();
        tv.volumeUp();
        tv.volumeDown();
        tv.powerOff();
    }

    public static void main(String[] args) {
        // - 이름이 없는 지역 내부 클래스 객체 생성
        // - TV라는 추상 클래스의 객체를 내부 클래스 형태로 생성했기 때문에,
        //  실제로는 TV 클래스를 상속한 내부 클래스가 만들어지게 된다.
        watchTV(new TV() {

            public void powerOn() {
                System.out.println("TV --- 전원을 켠다.");
            }
            public void powerOff() {
                System.out.println("TV --- 전원을 끈다.");
            }
            public void volumeUp() {
                System.out.println("TV --- 소리를 높인다.");
            }
            public void volumeDown() {
                System.out.println("TV --- 소리를 낮춘다.");
            }
        });
    }
}

//TV --- 전원을 켠다.
//TV --- 소리를 높인다.
//TV --- 소리를 낮춘다.
//TV --- 전원을 끈다.
// 이름이 있는 독립된 클래스로 구현
abstract class TV {
    public abstract void powerOn();
    public abstract void powerOff();
    public abstract void volumeUp();
    public abstract void volumeDown();
}

class AnonymousClass extends TV {
    public void powerOn() {
        System.out.println("TV --- 전원을 켠다.");
    }
    public void powerOff() {
        System.out.println("TV --- 전원을 끈다.");
    }
    public void volumeUp() {
        System.out.println("TV --- 소리를 높인다.");
    }
    public void volumeDown() {
        System.out.println("TV --- 소리를 낮춘다.");
    }
}

 

출처 - swexpertacademy.com/

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함