클래스 내부에 정의된 메서드의 모습
public static int abs(int n) { }
abs : 절대값 계산 메서드
sqrt : 제곱근 계산 메서드
random : 난수 발생 메서드
※ Math 클래스의 random과 같은 역할을 하지만 방식도 다르고,
static이 아니라 인스턴트 멤버메서드로 난수를 발생하는 클래스도 있다.
(Random클래스 Scanner처름 import해서 사용함)
Integer.parseInt
: String형으로 저장된 아라비아 기호들을 실제 숫자로 변환해주는
static 메서드
※ 변수 선언 시 final이라는 키워드도 붙일 수 있는데
이는 최초에 지정한 값이 끝까지 변경될 수 없는 변수로 만든다는 뜻
예) Integer.MAX_VALUE가 final 변수임!
new 인스턴스를 만들려고 할 때마다 새롭게 인스턴스가 만들어지는 것이 아니라 미리 만들어 놓은 인스턴스를 객체들이 새로 만들어지는 객체들과 공유해서 사용하게 하는 패턴
멤버변수들이 스태틱변수가 아니면서, 각 객체들이 공유해서 일관된 값을 가져야한다면,
덧붙여서 객체도 굳이 두 개 이상 만들 필요가 없는 상황이라면,
하나의 인스턴스를 만들고, 그 주소를 새로 만들어지는 참조변수들이 “공유”해서 사용하게 한다.
생성자를 private으로 보호한다.
클래스 내부에서 생성자를 호출해서 객체 하나(new 인스턴스)를 생성.
접속자(이용자)가 많을 수 있고 언제 들어올 지 모르기 때문에 미리 하나
만들어서 공유하게 한다
생성해 놓은 객체의 참조변수 값을 리턴하는 public형의 메서드를 생성
싱글턴은 공동 요소가 많고, 메서드를 주로 공유해서 사용할 때 많이 사용한다.
※ 만들어진 객체의 참조변수를 바로 print로 출력하면
➡️ 패키지이름.클래스이름@해시코드
※ 해시코드
: 중복된 값이 나오지 않게 하기위해서 실행된 알고리즘코드에 의해 나온
결과 값
생성자가 private로 보호되어 main메서드 안에서
new SingletonEx()로 새로운 객체 생성이 되지 않는다.
SingletonEx s1 = new SingletonEx()
=> ERROR!!!
싱글톤 방식은 클래스 내부에 유일한 객체(itc)를 생성해두고,
(private static 으로 생성)
public static 으로 만들어진 getInstance() 메서드를 호출하여
itc(생성한 객체)를 리턴 받아 그 객체를 사용
생성자 메서드는 static 인스턴스 itc만들 때 최초 실행된 때 말고는 실행되지 않는다.
주로 유지되어야 할 정보와 메서드를 많이 가지고 있는 클래스에서 주로 사용된다.
두 개의 객체가 유지되면 부담스러운 부분을 하나로 공유하고 필요한 내용을 멤버 변수로 해결하는 방식
싱글턴 패턴이 구현된 클래스의 활용
날짜, 시간에 관련된 정보를 제공하는 Calendar 클래스
(위 코드 블럭 참고)
클래스 실글턴 패턴이 구현되어 new 인스턴스를 사용한 객체 생성이 안된다.
반드시 getInstance메소드를 사용해야 한다.
객체 또한 새로 정의한 자료형이며 배열을 만들 수 있다.
그러나 생성과 사용에 다른 배열과 다른 점이 있다.
배열을 선언한 후 배열 하나하나에 뉴인스턴스 주소를 채워줘야 사용할 수 있다.
오늘까지 배운 내용들을 모두 활용해서 52장의 트럼프 카드를 생성하고, 랜덤하게 섞은 카드 덱을 만들고, 4명의 player에게 5장씩 나눠주는 게임을 만들어 보았다.
많은 클래스를 작성하고 오늘 처음 배운 내용들도 나오므로 다 같이 코드를 따라 작성해보면서 수업이 진행되었다.
※ toString은 다소 특별한 메서드이다.
toString 메서드가 포함된 클래스로 만든 객체는
System.out.println(객체이름(참조변수이름));
으로 출력하면
이전에 봤던 것처럼 "패키지.클래스이름@해쉬코드"가 출력되는 것이 아니라
toString 메서드에서 리턴해주는 값이 출력된다.
이는 System.out.println(객체이름(참조변수이름).toString());
를
출력한 결과와 윗 줄을 출력한 결과가 같다는 뜻
확인용 코드를 다 삭제하거나 주석처리한다.
4명의 player에게 한장씩 차례로 5번 나눠주고 (각자 5장을 갖게 되도록)
각 player가 어떤 카드를 가지고 있는지 한 줄에 출력한다.
player 모두 출력한다.
일반 초기화 블럭 : 객체 생성 시 실행(생성자와 성격이 비슷)
단순 값으로 초기화하는 경우 대입연산자를 통해서 처리할 수 있지만,
실행문이 포함된 초기화를 진행하는 경우 { }로 블럭을 만들어 초기화 과정을 정의할 수 있다. (아래 코드 블럭 참고)
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가 가능하다
(new) : 멤버변수들을 HEAP메모리에 로딩. 생성
생성자 메서드를 호출
멤버변수들을 HEAP메모리에 로딩, 생성
- 부모/자식 클래스의 모든 멤버변수를 한 번에 생성
자식클래스 객체가 생성되는 것이므로 자식클래스의 생성자가 먼저 호출
자식클래스의 생성자의 첫 번째 실행코드가 부모클래스의 생성자를 호출한다.
자식클래스의 생성자 명령 중 첫줄이 부모클래스의 생성자 호출이라는 뜻
자식클래스의 생성자 명령 첫줄은 super();
라는 명령이며,
따로 기술하지 않아도 존재하는 명령
디폴트 생성자처럼 꺼내서 직접 쓰기 전까지 숨어있는 명령이라고 할 수 있다.
부모클래스 생성자를 모두 실행한 후 자식클래스 생성자의 남은 명령을 실행한다.
자식 클래스에서 부모클래스 생성자 호출은 super();라고 명령하며,
반드시 첫 번째 실행코드로 써야 한다. (마치 this( );처럼)
this();
와 super();
의 관계는 내일 수업에서...
super() 명령은 꺼내도 되고 안꺼내도 상관이 없는데, 반드시 꺼내서 써야하는 경우가 있다.
부모 생성자가 매개변수가 존재하는 생성자로 대체되어 있는 경우
자식생성자의 첫줄명령( super( ); )을 꺼내놓지 않으면 자동으로 매개변수가 없는 디폴트 생성자를 호출한다.
이 때 부모생성자가 매개 변수 있는 생성자로 대체 되었다면 없는 부모생성자를 호출한 것이므로 ERROR!!
super();를 꺼내놓아도 ERROR!!
부모생성자의 매개변수에 맞게 호출을 변경해야 한다.
혹은 부모 생성자를 오버로딩 한다.(매개변수 없는 생성자 작성)
클래스 어렵다... 상속... 도 어렵고...
Singleton도 어떡하지...