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; //지역변수는 사용전 초기화 안하면 에러
}
}
기본값
변수 초기화
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 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 로 확인할 수 있다.
모듈 : 여러 패키지 및 자원을 모아 놓은 컨테이너
module > package
module-info.java, package-info.java 같은 파일을 통해 여러 옵션으로 관리할 수 있어 보인다.
인터페이스의
모든 멤버변수는 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();
구현한 클래스의 인스턴스를 인터페이스 타입의 참조변수로 참조하는 것이 가능하다.
원래는 둘 다 안됐으나
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 (다형성의 법칙)