DAY_012[국비] 자바 웹프로그래밍 과정

Bona의 블로그 입니다.·2022년 10월 13일
0

국비과정

목록 보기
13/99

 🌞 Day 012 : static메서드부터 상속까지 

  • 접근제어자를 구분하고 익숙해지자!!



 🥨 static method 

  • static 메서드
    : static 변수와 같이 프로그램 구동 전에 메모리에 로딩되어 객체 생성없이 호출될 수 있는 클래스의 멤버메서드
  • static 변수 사용과 같이 메서드 이름 앞에 클래스 이름과 '.'으로 연결해서 사용한다.
    객체 생성과 상관없이 사용한다.

 🎈 java.lang 패키지에 있는 클래스 중 static 메서드들의 실제 사용 예 

1. 간단한 수학적 계산을 위해 만들어진 Math 클래스의 static 메서드들

  • 클래스 내부에 정의된 메서드의 모습
    public static int abs(int n) { }

  • abs : 절대값 계산 메서드

  • sqrt : 제곱근 계산 메서드

  • random : 난수 발생 메서드

    ※ Math 클래스의 random과 같은 역할을 하지만 방식도 다르고,
       static이 아니라 인스턴트 멤버메서드로 난수를 발생하는 클래스도 있다.
       (Random클래스 Scanner처름 import해서 사용함)

  • static 메서드는 “클래스이름”을 앞에 두고 호출되고,
    인스턴스 메서드는 “객체이름”을 앞에 두고 호출

2. Integer 클래스 (int 타입의 자료형과 매칭되는 클래스)

  • Integer.parseInt
    : String형으로 저장된 아라비아 기호들을 실제 숫자로 변환해주는
    static 메서드

    ※ 변수 선언 시 final이라는 키워드도 붙일 수 있는데
       이는 최초에 지정한 값이 끝까지 변경될 수 없는 변수로 만든다는 뜻
       예) Integer.MAX_VALUE가 final 변수임!

3. Double 클래스 (double 타입의 자료형과 매치되는 클래스)

4. String 클래스 (int ➡️ String  /  double ➡️ String  /  boolean ➡️ String ...)


 🎈 static 변수/메서드 VS 인스턴스 변수/메서드 

💠 메서드에서 변수에 접근 가능성

  • 인스턴스 메서드 -> 인스턴스 변수  O
  • 인스턴스 메서드 -> static 변수       O
  • static 메서드 -> 인스턴스 변수       X
  • static 메서드 -> static 변수            O
    ( -> : 변수 접근 가능/불가능 )

💠 메서드들 간의 호출 가능성

  • 인스턴스 메서드 안에서 인스턴스 메서드 호출 style="color:blue">  O
  • 인스턴스 메서드 안에서 static 메서드 호출 style="color:blue">      O
  • static 메서드 안에서 인스턴스 메서드 호출       X
  • static 메서드 안에서 static 메서드 호출            O

💠 private static 변수

  • private으로 지정된 static멤버는 클래스의 내부에서만 사용이 가능한 멤버
  • private으로 지정된 static 변수를 이용(접근)하고자 한다면,
  • public으로 지정된 멤버메서드(static, 인스턴스)를 만들고 이용해야 한다.
  • 인스턴스 메서드에서도 접근은 가능하지만 객체 생성 후 이용이 가능



 ❤️ Singleton pattern ❤️ 

📢 중요!! 시험 문제임!!!

 🎈 Singleton pttern 이란? 

  • new 인스턴스를 만들려고 할 때마다 새롭게 인스턴스가 만들어지는 것이 아니라 미리 만들어 놓은 인스턴스를 객체들이 새로 만들어지는 객체들과 공유해서 사용하게 하는 패턴

  • 멤버변수들이 스태틱변수가 아니면서, 각 객체들이 공유해서 일관된 값을 가져야한다면,

  • 덧붙여서 객체도 굳이 두 개 이상 만들 필요가 없는 상황이라면,

  • 하나의 인스턴스를 만들고, 그 주소를 새로 만들어지는 참조변수들이 “공유”해서 사용하게 한다.

 🎈 작성 순서 

  1. 생성자를 private으로 보호한다.

  2. 클래스 내부에서 생성자를 호출해서 객체 하나(new 인스턴스)를 생성.
    접속자(이용자)가 많을 수 있고 언제 들어올 지 모르기 때문에 미리 하나
    만들어서 공유하게 한다

  3. 생성해 놓은 객체의 참조변수 값을 리턴하는 public형의 메서드를 생성

  • 싱글턴은 공동 요소가 많고, 메서드를 주로 공유해서 사용할 때 많이 사용한다.

    ※ 만들어진 객체의 참조변수를 바로 print로 출력하면
       ➡️ 패키지이름.클래스이름@해시코드
    ※ 해시코드
     : 중복된 값이 나오지 않게 하기위해서 실행된 알고리즘코드에 의해 나온
      결과 값

  • 생성자가 private로 보호되어 main메서드 안에서
    new SingletonEx()로 새로운 객체 생성이 되지 않는다.

  • SingletonEx s1 = new SingletonEx() => ERROR!!!

  • 싱글톤 방식은 클래스 내부에 유일한 객체(itc)를 생성해두고,
    (private static 으로 생성)
    public static 으로 만들어진 getInstance() 메서드를 호출하여
    itc(생성한 객체)를 리턴 받아 그 객체를 사용

  • 생성자 메서드는 static 인스턴스 itc만들 때 최초 실행된 때 말고는 실행되지 않는다.

  • 주로 유지되어야 할 정보와 메서드를 많이 가지고 있는 클래스에서 주로 사용된다.

  • 두 개의 객체가 유지되면 부담스러운 부분을 하나로 공유하고 필요한 내용을 멤버 변수로 해결하는 방식

  • 싱글턴 패턴이 구현된 클래스의 활용
    날짜, 시간에 관련된 정보를 제공하는 Calendar 클래스
    (위 코드 블럭 참고)
    클래스 실글턴 패턴이 구현되어 new 인스턴스를 사용한 객체 생성이 안된다.
    반드시 getInstance메소드를 사용해야 한다.



 🥨 객체 배열 

  • 객체 또한 새로 정의한 자료형이며 배열을 만들 수 있다.

  • 그러나 생성과 사용에 다른 배열과 다른 점이 있다.

  • 배열을 선언한 후 배열 하나하나에 뉴인스턴스 주소를 채워줘야 사용할 수 있다.



 🥨 Card Game 만들기 

  • 오늘까지 배운 내용들을 모두 활용해서 52장의 트럼프 카드를 생성하고, 랜덤하게 섞은 카드 덱을 만들고, 4명의 player에게 5장씩 나눠주는 게임을 만들어 보았다.

  • 많은 클래스를 작성하고 오늘 처음 배운 내용들도 나오므로 다 같이 코드를 따라 작성해보면서 수업이 진행되었다.

1. Card class 작성

  • 카드를 만들 class, 실행하지 않고 참고할 class이므로 main메서드를 만들지 않는다.

 toString은 다소 특별한 메서드이다. 
    toString 메서드가 포함된 클래스로 만든 객체는
    System.out.println(객체이름(참조변수이름));으로 출력하면
    이전에 봤던 것처럼 "패키지.클래스이름@해쉬코드"가 출력되는 것이 아니라
    toString 메서드에서 리턴해주는 값이 출력된다.
    이는 System.out.println(객체이름(참조변수이름).toString());
    출력한 결과와 윗 줄을 출력한 결과가 같다는 뜻

  • Card class가 잘 작성되었는지 테스트 해본다.

2. CardDeck class 작성

  • 이 클래스에서는 Card 클래스를 이용해서 52장의 카드를 만들고 배열로 만든다.
  • 52장의 카드의 배열이 잘 만들어지면 Math.random을 이용해서 카드들을 랜덤하게 섞어주는 shuffle메서드도 만들어 준다.

  • shuffle메서드 작성 전 카드를 몇 개 출력해보고,
    shuffle메서드 호출 후 랜덤하게 잘 섞였는지도 확인해보았다.

3. CardPaly class에서 테스트

  • 확인용 코드를 다 삭제하거나 주석처리한다.

  • 4명의 player에게 한장씩 차례로 5번 나눠주고 (각자 5장을 갖게 되도록)
    각 player가 어떤 카드를 가지고 있는지 한 줄에 출력한다.

  • player 모두 출력한다.



 🥨 초기화 블럭 

💠 일반 초기화 블럭

  • 일반 초기화 블럭 :  객체 생성 시 실행(생성자와 성격이 비슷) 

  • 단순 값으로 초기화하는 경우 대입연산자를 통해서 처리할 수 있지만,
    실행문이 포함된 초기화를 진행하는 경우 { }로 블럭을 만들어 초기화 과정을 정의할 수 있다. (아래 코드 블럭 참고)

💠 staic 초기화 블럭

  • static 초기화 블럭 :  static 멤버를 초기화하기 위한 영역 

  • 단순 값으로 초기화하는 경우 대입연산자를 통해서 처리할 수 있지만,
    실행문이 포함된 초기화를 진행하는 경우 static{ }로 블럭을 만들어 초기화 과정을 정의할 수 있다. (아래 코드 블럭 참고)

  • 일반 초기화블럭에서는 스태틱 멤버에 접근이 자유롭게 가능

  •  스태틱 초기화 블럭에서 인스턴스 멤버 접근은 제한된다. 

  • static 블럭은 객체 생성명령을 만나면 생성자 실행 이전에 실행



 🥨 상속 

 🎈 클래스들 간의 상속 

  • 클래스들 간의 상속(Extends)

  • 다수개의 클래스들이 중복되는 멤버변수 및 멤버메서드들을 가지고 있는 경우

    • 1차 목표
      : 부모자식관계를 생성하여  "코드의 중복을 방지" 

    • 2차 목표
      :  "코드의 재활용"  코드의 중복이 발생하고 있는 클래스에서
      중복되는 멤버들을 별도의 클래스로 생성하고 상속을 구현한다.

  • 부모의 멤버들을 상속한 자식 클래스 생성
    class 자식클래스명 extends 부모클래스명 { }
    부모의 멤버들은 상속한 클래스에는 별도의 언급이 없어도
    부모의 멤버변수, 멤버메서드가 있는 걸로 인식된다.

  • 상속 해주는 클래스 : 슈퍼(super)클래스, 부모클래스, 상위클래스

  • 상속을 받는 클래스 : 서브(sub)클래스, 자식클래스, 하위클래스

  • 예시 1

  • 예시 2


 🎈 접근지정자와 상속 

  •  private 
    : 현재 클래스 내에 있는 멤버 메서드를 통해서만 접근 가능한 완전 은닉

  • 부모 클래스에 private로 감춰진 n1이라는 변수가 있을 때
    public int getN1(){ return n1; }라는 이 메서드는...

    • 자식 클래스에서 만들어진 getN1은 ERROR
      부모 클래스에서 만들어진 getN1은 에러가 아님

    • 부모 클래스에서 만들어져 있다면 이는 상속되어 자식클래스에도 있는 것으로 인식될 예정이며, public 이므로 어디서든 객체가 생성되면 자유롭게 호출이 가능 하다.

  • 접근 지정을 아무 것도 하지 않은 멤버 ➡️  default 로 지정된다.
    이는 동일한 패키지 내부에서는 public, 다른 패키지에서는 private으로 동작

  •  protected 
    : 자식 클래스에서는 public과 같으며, 외부로 부터는 private로 작동
      부모클래스의 protected는 자식 클래스에게 public과 같다.

  • 부모클래스의 private멤버는 아무리 자식 클래스여도 접근할 수 없다.
    부모클래스의 private멤버는 access할 수 없다.

  • public으로 생성된 멤버메서드를 이용하면 부모의 private멤버에도 access가 가능하다


 🎈 객체의 생성 과정 

💠 일반(상속관계가 없는) 객체의 생성과정

  1. (new) : 멤버변수들을 HEAP메모리에 로딩. 생성

  2. 생성자 메서드를 호출

💠 상속관계 있는 객체(자식객체)의 생성과정

  1. 멤버변수들을 HEAP메모리에 로딩, 생성
    - 부모/자식 클래스의 모든 멤버변수를 한 번에 생성

  2. 자식클래스 객체가 생성되는 것이므로 자식클래스의 생성자가 먼저 호출

  3. 자식클래스의 생성자의 첫 번째 실행코드가 부모클래스의 생성자를 호출한다.

    • 자식클래스의 생성자 명령 중 첫줄이 부모클래스의 생성자 호출이라는 뜻

    • 자식클래스의 생성자 명령 첫줄은 super();라는 명령이며,
      따로 기술하지 않아도 존재하는 명령

    • 디폴트 생성자처럼 꺼내서 직접 쓰기 전까지 숨어있는 명령이라고 할 수 있다.

  4. 부모클래스 생성자를 모두 실행한 후 자식클래스 생성자의 남은 명령을 실행한다.

    • 구조가 이렇게 짜여진 이유는 부모클래스의 private멤버를
      자식클래스의 생성자에서 초기화 할 수 없으므로
      부모클래스 생성자를 통해 접근하고 초기화하기 위함이다.

💠 반드시 super( );를 써야 하는 경우

  • 자식 클래스에서 부모클래스 생성자 호출은 super();라고 명령하며,
    반드시 첫 번째 실행코드로 써야 한다. (마치 this( );처럼)

  • this();super();의 관계는 내일 수업에서...

  • super() 명령은 꺼내도 되고 안꺼내도 상관이 없는데, 반드시 꺼내서 써야하는 경우가 있다.

    • 부모 생성자가 매개변수가 존재하는 생성자로 대체되어 있는 경우

    • 자식생성자의 첫줄명령( super( ); )을 꺼내놓지 않으면 자동으로 매개변수가 없는 디폴트 생성자를 호출한다.

    • 이 때 부모생성자가 매개 변수 있는 생성자로 대체 되었다면 없는 부모생성자를 호출한 것이므로 ERROR!!

    • super();를 꺼내놓아도 ERROR!!
      부모생성자의 매개변수에 맞게 호출을 변경해야 한다.
      혹은 부모 생성자를 오버로딩 한다.(매개변수 없는 생성자 작성)



 🥐 마무리... 

  • 클래스 어렵다... 상속... 도 어렵고...

  • Singleton도 어떡하지...



profile
제가 공부하고 공유하고 싶은 글을 올리고 있습니다.

0개의 댓글