본문 바로가기
코딩

2022.02.18_10일차_내부클래스와 익명클래스, 예외처리

by 흥뷰자 2022. 2. 24.

10차 학습내용

1. 싱글턴 Singleton
2. 내부클래스 inner class, 중첩클래스, newsted class
3. 익명 클래스 annonymous class  대괄호부분
4. 예외처리 

 

 

 



1. 싱글턴 Singleton (싱글인스턴스)  객체생성 하나만 해놓고 계속 쓰게 하는 것 


객체생성을 줄여 메모리 낭비를 줄여
외부에서 new로 생성자를 호출할 수 없도록 막아놓는다.

1) 구성요소

1 - 자기 클래스 타입의 private static 변수 
: 내 클래스안에 한번만 객체생성하여 로딩되게 미리 만들어놓고
  값변경도 외부에서 못하게 private으로 처리
private static 클래스명 instance = new 클래스명();

2 - private 생성자 : 외부에서 객체생성 못하게 막기
private 클래스명() {}

3 - 외부에서 instance를 가져다 쓸수 있도록 get메서드 public으로 생성///set은 안해놓음. private훼손못하게할거니까
외부에서 객체생성이 안되므로, 메서드도 static 붙여
public static 클래스명 getInstance() {
return instance;
}




2. 내부클래스 inner class, 중첩클래스, newsted class  

 


클래스 내부에 또 다른 클래스를 정의한 것.
이유 : 은닉화 위해 사용
보안강화, 코드 간경, 멤버 쉽게 접근.



1) 구조


class 외부클래스 {
       외부변수..
       외부 메서드...

        class 내부클래스 {
                내부변수..
                내부 메서드...

         }

 


2) 종류 : 클래스 정의(선언) 위치에 따라 구분


      1. 멤버 클래스 


                 1 - 인스턴스 멤버 클레스
           : A클래스 생성해야만 사용할 수 있는 내부 클래스B
class A {
        ..
        class B {
                ..
        }
}

                  2 - static 멤버 클래스
           : A클래스를 통해 바로 접근 가능한 B 내부클래스 A.B
class A {
       ..
       static class B {
               ..
        }
}
* 멤버클래스도 하나의 클래스이므로
  컴파일하면 바이트코드파일(.class) 별도로 생성된다.
A$B.class 


         2. 로컬 클래스


: method()가 실행될때만 사용할 수 있는 B 내부클래스
class A {
      void method(){
            class B {
                   ...
            }
      }
}

* A$1B.class


3) 인스턴스 멤버 클레스


: 인스턴스 변수와 메서드만 선언가능, static 변수와 메서드 선언 불가 (객체 생성되기도 전에 존재할수 없는데 존재하라는거니까).. 근데 내부 클래스 static은 가능..

# 정의
class A {

       int z;              
       class B {
                 B(){}
                 int x;
                 void method(){..}    // B클래스 내부에서 z를 부를 때는 그냥 z라고도 쓸 수 있지만, a.this.z 도 가능하지     
                 // static int y;  (X) 이건안됨
                 // static void method2() {..}  (x) 이것도 안됨 


# 객체 생성 
: A 외부에서 B 생성 -> A객체생성 후 B객체생성

A a = new A();   //A객체생성(A:외부클래스/ a:외부참조변수)
A.B b = a.new B();    //B객체생성(외부참조변수(a)로 B:내부클래스)
b.x = 10;
b.method();


4) static 멤버 클래스


: static 키워드가 붙은 내부 클래스.
  모든 종류의 변수와 메서드 선언 가능.
# 정의
class A {
      static class B {
            B(){}
            int x;
            void method(){..}
            static int y;  내부클래스 자제도 클래스니까 다된다.
            static void method2() {..} 

# 객체 생성
A외부에서 B생성 -> A 객체 생성 필요 없음.

A.B b = new A.B(); // 객체생성
b.x = 10; // 인스턴스 멤버 //쓰는 결과는 같아보여도 A객체 생성을 따로 안했어용
b.method();
A.B.y = 20; // 클래스 멤버 이건 스태틱이라 위에 객체생성 안해도 바로 쓸 수 있다
A.B.method(); // 이건 스태틱멤버라 위에 객체생성 안해도 바로 쓸 수 있다


5) 로컬(지역) 클래스


: 메서드 안에 정의
: 접근제어자와 static을 붙일 수 없다 (메서드 안이라 제약이 있는것)
  메서드 실행할 때 메서드 내부에서만 사용되므로 제한할 필요가 없다. (메서드 끝나면 끝나니까)
  인스턴스변수와 메서드만 선언 가능.
# 정의 
void methodA() {
      class B {
            B(){}
            int x;
            void method(){..}
            // static int y;  (X) 이건안됨
            // static void method2() {..}  (x) 이것도 안됨 

       }
#객체 생성 선언된 위치에서 동등하게 생성, 메서드 내부.
       B b = new B();
       b.x = 100;
       b.method(); 
}




3. 익명 클래스 annonymous class  


: 이름이 없는 클래스
객체 이름이 없지만 클래스를 정의하고 동시에 객체를 생성함.
변수의 초기값, 지역변수의 초기값, 매개변수의 매개값으로 주로 대입됨.
단독으로 생성 불가, 클래스를 상속하거나 인터페이스를 구현해야 생성가능.


1) 구조 : 정의와 동시에 객체생성 한번에. 단발성으로 사용  
new 클래스명(){            //기준점(상속의 일부로 볼수.. 아래 재정의 오버라이딩)
// 클래스 정의..
}
(선언까지)
바로 쓰려면 }.메서드명()

new 인터페이스명(){         //기준점
// 메서드 오버라이딩...
}

< Anony01
< 하나 더해보기 Anony02

< 지역변수의 초기값으로 해보기

< 매개변수 인자값으로 익명클래스를 전달



4. 예외처리  


: 코드로 발생할 수 있는 에러를 미리 진단하고, 해결방안을
코드로 처리해 놓은 것.
- 컴파일 에러 : 컴파일(프로그램 번역.class) 할 때 발생 (실행조차 안됨) : 문법 오류
- 런타입 에러 : 실행하다 발생 : 문법적으로 맞아 컴파일은 되는데
입력오류 등으로 실행도중 에러

1) 예외(Exception) 에러(Error)
예외 : 프로그램 코드로 해결 가능한 것들.
에러 : 문법적으로 해결 못하는 것들 ...
2) 방법 : try-catch 구문   //////메서드 안에 작성
try {
// 예외가 발생할 것 같은 코드들...
}catch(ArrayIndexOutOfBoundsException e) {
// 예외가 발생하면 대처할 코드들...
}catch(Exception e) { // 부모타입 예상 외의 에러를 받아줌. 맨 아래에 작성
// 
}

3) 대표적인 예외 (클래스로 만들어 놓음) 
ArrayIndexOutOfBoundsException : 배열 인덱스 범위 잘못
ClassNotFoundException: 찾는 클래스가 없다
ArithimeticException : 정수를 0으로 나누려할 때
ClassCastException : 변환할 수 없는 타입으로 객체를 형변환할 때
NullPointerException : 생성안하고 쓰려고 할 때...
IllegalArgumentException : 잘못된 인자 전달시 발생..
NumberFormatException : 문자 -> 숫자 형태가 안맞아 발생
InterruptedException : thread가 멈춰있다 다시 실행안하거나,
일시정지인데 완전히 꺼지거나 하는 경우
IOException : 입출력(input, output) 동작 실패 또는 인터럽트시 발생
OutOfMemoryError : 메모리 부족시 발생


 < ArithimeticException
< for문 밖 안 차이
<TestEx04 NumberFormatException 
포문 내부에서 디테일하게 묶어보기 포문으로 다시 나가는 것 i--; continue;
numberFormatException 10000 

4) finally (옵션. 가장 마지막 캐치 아래에 작성)
예외 여부와 상관없이 무조건 실행되는 블럭

try{
예외 발생할거같은 코드들..
}catch(Exception e) {
예외 발생시 처리해줄 코드..
}finally{
예외 발생과 상관 없이 무조건 실행되는 문장
}

 실행순서 캐치로 넘어가면 다시 못돌아감. 포문으로 넣지 않으면 불가능 <TestEx05 1:15


5) 예외 발생 시키기  TestEx06 강제에러 발생 명령 - 코드는 문제 없지만 상황상 사용자가 쓸때 에러여야 하는 때
: 고의로 예외 발생시키는 것.

Exception e = new Exception();
throw e;  // throw 명령어

trycatch로 묶지 않고 쓰는건 컴파일 오류 발생 안되지만 실행시 오류남 , 
db쪽 에러에서 try catch구문을 강제시키는 경우도 있음. 이건 컴파일도 안됨. 

JSP에서 주구장창 쓰는건데...

부모인 Exception은 맨 밑으로 보내야 한다. <3:2 TestEx07

예외를 토스 시키는 방법: --> 처리는 메서드를 호출하는 쪽에서
메서드 선언부 () throws Exception클래스, ..{ }
void method() throws Exception{
throw new Exception();
}


6) 상속 구조  
Object
  |
Throwable
/   \
Exception    Error
/  /  \  \    / \  \

좀더 복잡한 예외처리 Throws   
unhandled exception : try-catch로 묶으라는 의미. 예외처리를 하라는 의미
부르는 쪽에서 예외처리하지 않으면 또 토스해야함...  
그렇지 않으면 상황에 맞게 예외처리
토스되는거 스프링가면 많이볼거....

조금 다른경우 
처리도 하고, 토스도 하는 경우 : 가져다 쓰는 애에서도 또 처리하게 토스


우리만의 예외 만들기 


문법정리
1. 메모리 로딩순서 
클래스 -> static -> main실행 --> new~~
2. 클래스 
클래스 변수           클래스명.변수명
인스턴스 변수 객체생성 후 변수명

매서드 안의 우선순위(이름이 같은 경우) 지역 -> 인 -> 클
3. 메서드2
클래스 메서드 인스턴스 메서드
메서드는 실행한곳으로 돌아옴 리턴이 없으면 void 
매개변수 부를 때 인자 수 순서 타입 개수 같아야
초기화 3가지 명시적 초기화블록(스테틱, 인스턴스 블록)
생성자 클래스명(){}
메서드 생성자 둘다 오버로딩 됨

오버로딩의 조건 ? 이름같지만 매개변수 개수 타입 순서 달라야

클래스 만들 때 생성자 작성한적이 없으면 기본생성자로 호출 가능. 내부적 생성
기본생성자 아닌 매개변수있는 생성자 만들면 기본생성자 불가능.

상속 클래스 1:1 부모자식관계 
모든클래스의 부모 Object클래스
상속 변수와 메서드
오브젝트말고 아무것도 상속받지 않은 클래스는 단일클래스

접근제어자, 클래스 앞에 붙을 수 있는 것 (한개): public default

메서드나 변수 앞에 붙는것 4가지 public protected dafault private

캡슐화 방법 - 변수는 private으로 만들고 그에 접근하는 메서드를 public으로 오픈해둔다

private int 변수를 캡슐화 해야한다면 - public int getAge() {return age;} 외부에서 가져옴(가져다쓰는사람입장)
set메서드 public void setAge(int age) {this.age = age;}

this : 객체자기자신
this() : 내 생성자(클래스) 안 내 옆 다른 생성자. 가장 첫번째로 와야함
super : 부모의
super() : 자식 생성자 안에서 부모생성자를 부를 때. 가장 첫번째로 와야함.


다형성 : 코드 작성  - 조상의 변수에 자식 객체 담을 수 있다.
조상 변수에 담아놔도 객체가 자식이라면 오버라이딩된 메서드가 불린다. (오버라이딩: 덮어쓰기 조건: 상속관계에서 성립 + 부모로부터 물려받은 메서드의 기능을, 자식이 내용물만 고쳐쓴 것) 동적바인딩 부모꺼무시한자식꺼가실행된다. 

추상클래스 : abstract 
안에 들어갈수있는 것 - 추상메서드, 상수, 메서드, 일반변수 (즉일반클래스에 추상메서드 하나들어간것. 하나라도 있으면 클래스앞에도 abstract붙여야)
-> 사용 : 상속받아 구현된 클래스를 작성해서 써야
abstract class A {
       abstract void func();
    }
사용 구현을 해야 추상클래스가 되지 않음
class B extends A{
void func(){
...

}
객체생성 B로해야. 
인터페이스 : interface  
추상메서드와 상수만 들어갈수있음. 
전부 public접근제어자 붙여야함.
상수는
public static final int ABC;
추상메서드는
public abstract void add();
void test();
int BBB; 축약형

쓰려면. 이름. 내부 다 구현해줘야
class Hahaha implements ABCInterface {
public void add(){}
public void test(){}
}

인터페이스끼리 상속가능, 다중상속도 가능. 
구현한 클래스를 만들 때 다중구현도 가능. 

class Hahaha implements ABCInterface, DEFInterface {
public void add(){}
public void test(){}
}



 

댓글