velog에서 이전한 글 입니다.
23.5.2 ~ 23.5.19 사전 캠프 기간의 TIL 기록이다.
TIL: Today I Learned
멤버 변수 초기화
class InitTest{
int x;
int y = x; // 멤버변수는 초기화 하지않아도 기본값으로 초기화
private void method1(){
int i;
int j = i; //지역변수는 사용전 초기화 안하면 에러
}
}
- 기본값
- boolean : false
- char : '\u0000'
- 참조형 : null
- 변수 초기화
- 클래스 변수(cv) 초기화 -> 인스턴스 변수(iv) 초기화
- 자동 초기화 -> 명시적 초기화 -> 초기화 블럭, 생성자
class Main{
static {
System.out.println("클래스 초기화 블럭");
}
{
System.out.println("인스턴스 초기화 블럭");
}
private Main(){
System.out.println("인스턴스 생성자");
}
public static void main(String[] args){
System.out.println("Start Main");
Main t = new Main();
Main t2 = new Main();
}
}
결과
클래스 초기화 블럭
Start Main
인스턴스 초기화 블럭
인스턴스 생성자
인스턴스 초기화 블럭
인스턴스 생성자
클래스 초기화 블럭이 가장 먼저 한 번 동작하고 인스턴스 초기화 블럭이 생성자보다 먼저 수행된다.
멤버변수 변경은 getter setter 메서드 만들어하자.
제어자
접근 제어자
- 클래스 : public, (default)
- 메서드/멤버변수/생성자 : public, protected, (default), private
- 지역변수 : X
기타 제어자
- final
- class : 변경 불가, 확장 불가
- method : 오버라이딩 불가
- 멤버변수/지역변수 : 상수로 동작
- abstract
- 클래스 : 클래스 내에 추상 메서드가 있음을 의미.
- 메서드 : 선언만 했고 구현부 작성안한 추상 메서드임을 알림.
다형성, 참조변수
- 다형성 : 부모 타입의 참조변수로 자식의 인스턴스를 참조할 수 있도록 한 것으로부터 나오는 여러 형태
- 매개변수의 다형성 : 매개변수를 부모 타입으로 받아 공통으로 처리할 수 있다.
참초변수의 형변환
public class Main {
public static void main(String[] args) {
Car car = new Car();
FireCar firecar = new FireCar();
Car re_firecar = (Car) firecar;
FireCar re2_firecar = (FireCar) re_firecar;
re2_firecar.fire();
// FireCar re_car = (FireCar) car; // 여기부터 에러
// re_car.fire();
System.out.println( car instanceof FireCar); //false
}
}
class Car{
void say(){
System.out.println("Car");
}
}
class FireCar extends Car {
void fire(){
System.out.println("fire!");
}
}
자식이 부모로 형변환은 문제없으나 부모가 자식으로 형변환은 명시적이어야 한다. 사실 자식 -> 부모 -> 자식 가는게 아니면 못하는 듯 하다.
형변환 가능 여부는 instanceof 로 확인할 수 있다.
+α
- toString()은 Object 클래스의 메서드
- 참조변수 + 문자열 = 참조변수.toString() + 문자열
모듈/패키지
모듈 : 여러 패키지 및 자원을 모아 놓은 컨테이너
module > package
module-info.java, package-info.java 같은 파일을 통해 여러 옵션으로 관리할 수 있어 보인다.
interface
인터페이스의
- 모든 멤버변수는 public static final 이어야 한다.
- 모든 메서드는 public abstract 이어야 한다.
둘 다 생략 가능하며 컴파일 시에 자동으로 추가해준다. - 상속과 구현 동시가능
class A extends B implements C{
public void c(){
System.out.println("a가 구현한 c");
}
}
interface C{
/** 구현해야할 c 설명 */
void c(); //public abstract 생략
}
- 인터페이스 타입의 매개변수 : 메서드 호출 시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야 함을 의미한다.
- 리턴타입이 인터페이스 : 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다.
인터페이스를 이용한 다형성
Fightable f = (Fightable)new Fighter();
또는
Fightable f = new Fighter();
구현한 클래스의 인스턴스를 인터페이스 타입의 참조변수로 참조하는 것이 가능하다.
default/static method
원래는 둘 다 안됐으나
static 메서드는 인스턴스와 관계없는 독립적인 메서드로 추가 못할 이유가 없었다.
default는 인터페이스를 변경되지 않는게 최고이지만 언젠가 변경은 발생하기 마련이었고 그에 따른 대책이다. ( 추상 메서드를 추가하면 구현한 기존의 모든 클래스들이 새로 추가된 메서드를 구현해야하므로 )
interface Test{
static void saystack(){
System.out.println("say stack");
}
default void say() {
System.out.println("hello");
}
}
마찬가지로 public은 생략가능하다.
충돌 해결 규칙
- 여러 인터페이스의 디폴트 메서드 간의 충돌 -> 구현한 클래스에서 오버라이딩 해야한다.
- 디폴트 메서드와 부모 클래스의 메서드 간의 충돌 -> 부모 메서드가 상속되고 디폴트는 무시된다.
익명 클래스
class Animal {
public String bark() {
return "동물이 웁니다";
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Animal() {
// @Override 메소드
public String bark() {
return "개가 짖습니다";
}
// 새로 정의한 메소드
public String run() {
return "달리기 ㄱㄱ싱";
}
};
dog.bark();
dog.run(); // ! Error - 외부에서 호출 불가능
}
}
⬆출처
위 코드 처럼 클래스 정의와 동시에 객체를 생성할 수 있으며 일회성 오버라이딩 용으로 사용한다.
오버라이딩 한 메소드 사용만 가능하고, 새로 정의한 메소드는 외부에서 사용이 불가능 하다는 점을 주의하자. 새로 메서드를 정의해도 Animal에는 없는 메소드이므로 Err (다형성의 법칙)
'Language > Java' 카테고리의 다른 글
자바) List/ Stack/ Arrays Comparator/ Comparable Iterator (23-05-09) (0) | 2023.07.13 |
---|---|
자바) lang/ Object/ StringBuffer/ equals (23-05-08) (0) | 2023.07.13 |
자바) static import/ 예외처리 (23-05-05) (0) | 2023.07.13 |
자바) Wrapper/ 표현식/ 이름붙은 반복문 (23-05-04) (0) | 2023.07.13 |
자바) JDK/ JVM/ Runtime Data Areas (23-05-02) (0) | 2023.07.13 |