- 추상 클래스처럼 내부에 추상 메서드를 지닐 수 있는 것 - 인터페이스 내부에 선언하는 메서드는 모두 자동으로 public abstract가 된다 - 인터페이스 내부에 선언하는 변수들은 자동으로 final static이 된다 - 인터페이스는 인스턴스화 하는것이 불가능하다 - 인터페이스는 클래스에게 특정 성질을 부여하기 위해 사용한다 Serializable -> 직렬화가 가능한 객체가 된다 Comparable -> 비교가 가능한 객체가 된다 - 추상 클래스는 인터페이스 영역이 존재하지만 인터페이스에는 인스턴스 영역이 아예 없다 - 추상 클래스는 하나 밖에 상속받지 못하지만 인터페이스는 여러개 구현받을 수 있다
interface Swimmer {
// interface 내부의 메서드는 자동적으로 public abstract가 된다
void swim();
}
interface Runner {
void run();
}
class Whale implements Swimmer {
@Override
public void swim() {
System.out.println("고래는 수영을 아주 잘합니다.");
}
}
- public : 다른 패키지의 다른 클래스에서 해당 자원에 접근할 수 있다 같은 패키지의 다른 클래스에서도 접근할 수 있다 - protected : 다른 패키지의 다른 클래스에서 상속받는 경우에만 접근할 수 있다 일반적으로 사용하는 경우, 다른 패키지에서는 접근할 수 없다 같은 패키지의 다른 클래스에서는 접근할 수 있다
- default : 다른 패키지에서 접근할 수 없다 같은 패키지의 다른 클래스에서는 접근할 수 있다 - private : 다른 패키지에서 접근할 수 없다 심지어 같은 패키지의 다른 클래스에서도 접근할 수 없다 현재 클래스 내부에서만 사용할 수 있는 자원이 된다
public class C09_AccessModifierTest {
public int a1 = 10;
protected int a2 = 10;
int a3 = 10;
private int a4 = 10;
public void method1() {
System.out.println("public");
}
protected void method2() {
System.out.println("protected");
}
void method3() {
System.out.println("default");
}
private void method4() {
System.out.println("private");
}
}
예시를 위해 먼저 접근제어자를 테스트해볼 다른 클래스(C09_AccessModifierTest)를 생성
public classC09_AccessModifierextendsmyobj.C09_AccessModifierTest
C09_AccessModifierTest 를 상속받는C09_AccessModifier클래스 생성
(다른 패키지의 클래스를 상속받으면 public과 protected까지 사용할 수 있다)
현재 같은 패키지내에 존재하는 다른 클래스를 불러 사용하는 경우 (private을 제외하고 모두 사용할 수 있다)
이번엔 다른 패키지에 똑같이 생성
package myobj;
public class C09_AccessModifierTest {
public int a1 = 10;
protected int a2 = 10;
int a3 = 10;
private int a4 = 10;
public void method1() {
System.out.println("public");
}
protected void method2() {
System.out.println("protected");
}
void method3() {
System.out.println("default");
}
private void method4() {
System.out.println("private");
}
}
- 모든 클래스들의 최고 조상 클래스 - 자바에 존재하는 모든 객체는 Object 클래스의 자손이다 - Object 클래스의 메서드는 모든 클래스 내부에 이미 상속받아져서 존재하고 있다 - Object 클래스의 메서드는 주로 해당 클래스에 맞는 형태로 오버라이드 하여 사용하게끔 설계되어 있다
# toString()
- "해당 객체를 문자열로 표현한다면 어떤 모양이어야 하는가"를 정의해두는 메서드
- 자바의 모든 객체는 toString()을 통해 문자열로 표현될 수 있다 - Object클래스에 정의되어있는 toString()의 원형은 해당 클래스의 이름과 메모리상의 주소값을 출력하게 되어있다 - toString() 기본 동작이 싫다면 해당 메서드를 오버라이드하여 사용하면 된다
class TStory {
}
여기 TStory 클래스가 있다
TStory ts = new TStory();
System.out.println(ts);
toString()이 오버라이드 되있지 않아 클래스 이름 (TStory) @ 메모리상의 주소 (515f550a) 가 나온다
class TStory {
@Override
public String toString() {
return String.format("HelloWorld %d", 44);
}
}
toString()을 오버라이드하여 toString() 출력 결과를 바꿀 수 있다
# equals(obj)
- "두 인스턴스가 같다고 판정하는 기준은 무엇인가"를 정의해두는 메서드 - 매개변수로 전달받은 인스턴스와 현재 인스턴스(this)를 비교하여 결과를 리턴한다 - Object 클래스에 정의되어있는 기본 동작은 두 인스턴스가 같은 인스턴스인지를 비교하게끔 만들어져 있다
String first = "안녕";
String second = "안녕";
System.out.println(first.equals(second));
두 인스턴스를 비교하여 boolean타입으로 값을 반환한다
# hashcode()
- "해당 객체를 유일하게 구분할 수 있는 값은 무엇인가"를 정의해두는 메서드 - 해당 인스턴스의 지문 같은 역할을 하는 메서드 - Object 클래스에 정의되어있는 기본 동작은 해당 인스턴스의주소값을 리턴하게끔 구현되어 있다 - 자바의 모든 객체는 toString()을 통해 문자열로 표현될 수 있다 - Object클래스에 정의되어있는 toString()의 원형은 해당 클래스의 이름과 메모리상의 주소값을 출력하게 되어있다
- 객체가 다양한 형태를 지닐 수 있다는 성질 - 강아지는 강아지이기도 하고 동물이기도 하다 강아지는 동물이다(o), 동물은 강아지다(x) - 아메리카노는 아메리카노이기도 하고 커피이기도하다 아메리카노는 커피이다(ㅇ), 커피는 아메리카노이다(x) - 자식 클래스 인스턴스는 부모 클래스 타입의 변수에 대입될 수 있다
# 업 캐스팅
- 자식 타입 인스턴스가 부모 타입이 되는 것 - 자식 타입은 아무 문제 없이 부모 타입이 될 수 있다 - 업 캐스팅 된 상태에서는 자식 클래스였을때 가지고 있던 기능은 사용할 수 없다 - 자식클래스 인스턴스가 업 캐스팅 된 상태에서 오버라이딩된 메서드를 사용하는 경우 자식 클래스의 메서드(자식 클래스에서 마음대로 개조한 메서드)가 실행된다
# 다운 캐스팅
- 부모 타입은 일반적으로 자식 타입이 될 수 없다 - 업캐스팅되었던 자식 클래스의 인스턴스만이 다시 원래의 타입으로 돌아올 수 있다 (ex> 원래 강아지였던 인스턴스만 다시 강아지로 돌아올 수 있다)
# instanceof 연산자
- 해당 인스턴스가 특정 클래스의 인스턴스인지 검사해주는 연산자 - 결과는 true/ false로 알려준다
- 이미 만들어져 있는 클래스를 그대로 물려받아 사용하는 문법 - 자식 클래스는 부모로부터 모든 변수와 메서드를 물려받아 그대로 가지고 있다 - 자식 클래스는 부모로부터 물려받은 변수 및 기능을 마음대로 수정해서 사용가능 (오버라이드, Override) - 자식 클래스에는 부모 클래스에는 없는 기능을 새로 추가해서 사용가능 - 상속시 자식 클래스에서는 반드시 부모클래스의 생성자를 가장 먼저 호출해야 한다
# super
- 자식 클래스로 생성된 인스턴스의 부모 부분을 의미한다 - 자식 클래스에서 this는 자식 클래스 자신을 의미, super 부모 부분 의미 - 자식 클래스와 부모 클래스에서 같은 이름을 가지고 있는 자원을 구분하기 위해서 사용한다 - this()는 현재 클래스의 생성자를 의미하고 super()는 부모 클래스의 생성자를 의미한다
- 인스턴스 영역의 반대 개념 - 같은 클래스로 만들어진 모든 인스턴스들이 함께 사용하는 공동 영역 - 앞에 static이 붙은 자원들은 모든 인스턴스들이 함께 사용하는 공동의 자원이 된다 - static 영역의 자원은 인스턴스 이름이 아닌 클래스 이름으로 접근이 가능하다 - 스태틱 영역은 인스턴스가 하나도 생성되지 않은 시점에도 존재한다 (최초로 해당 클래스가 호출되었을 때 생성된다) - 스태틱 영역의 값은 인스턴스 영역에 활용할 수 있지만인스턴스 영역의 값은 스태틱 영역에 활용할 수 없다
static을 붙일 수 있는 자원
- 스태틱 변수 (모든 인스턴스에서 항상 같은 값을 가지는 공동의 변수) - 스태틱 메서드 (인스턴스가 존재하지 않을 때도 동작할 수 있는 메서드) - 클래스 내부의 스태틱 클래스
알아보기 위해 먼저 TrumphCard 라는 클래스를 만들어보자
class TrumphCard {
int rank; // A ~ K
int suit; // 하트, 스페이드, 다이아몬드, 클로버
카드의 모양(suit)과 숫자(rank)는 모든 인스턴스에서 달라야 하는 값이므로static변수로 설정하지 않는다
static int card_width = 80;
static int card_height = 150;
카드의 너비(card_width)와 높이(card_height)는 모든 인스턴스에서 다를 필요가 없는 값이다 이런 성질의 변수를 인스턴스 값으로 두면 메모리의 공간이 낭비된다