개발하는 삶
[Java] 상속, 인터페이스 본문
상속
- 자손의 멤버개수는 조상보다 많거나 같다
- 조상의 static 메서드는 상속이 불가능
- 하나의 부모만 상속
- final 클래스는 부모클래스가 될 수 없음 (String 클래스가 대표적인 예)
- 모든 클래스는 Object를 상속받음
- Object에 정의된 11개의 메서드를 상속받음
- 상속은 아니지만. 클래스 내에 다른 클래스 참조변수를 선언할 수 있다
- Parent p = new Child(); 일 때,
- p는 참조변수.
메서드 : 정의된 클래스에 따라가는데, 상속받은 클래스를 구현한 것만 인정(new Child())
멤버변수: 참조변수의 타입에서 참조됨 (Parent p)
- p는 참조변수.
다형성
- 참조변수의 형변환
- 조상-자손 관계에서만 가능
- 기존 객체의 기능(조상) + 좀더 업그레이드 된 기능(자손) 을 활용하기 위해 씀
- 자손타입을 조상타입으로 바꾸면 둘의 교집합만 가져가고(교집합 아닌거는 불러올수없음)
- 대신에 자손타입에서 오버라이딩 된건 그대로 쓴다
- 조상타입 참조변수 <= 자손타입 객체를 대입하고싶을 때
- smartTv st = new smartTv();
- Tv t = (Tv) st;
- 앞에 (조상객체) 형변환을 붙여주면 됨 (형변환 생략 가능)
- 자손타입 참조변수 = (자손객체) 조상타입참조변수 라면, (강제 타입변환)
- 자식타입이 부모타입으로 변환되어있는 상태에서만 가능
- smartTv st = (smartTv) t ;
- (형변환 생략 불가능)
- 자식 -> 부모타입 -> 다시 자식으로 돌아올때
- 조상-자손 관계에서만 가능
- instanceof : 형변환 가능한지 물어보기
- t instanceof smartTv
- 참조변수 instanceof 형변환할 객체
- 인터페이스로 변환된 매개변수 -> 다시 구현 클래스로 강제타입변환하기 전에도 사용
자손객체 배열로 담기
Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();
패키지
- 클래스의 묶음
- 클래스의 이름은 패키지를 포함해있다 ex. java.lang.String
- 클래스 이름이 같아도 패키지가 다르면 다른 클래스로 인식
- 패키지 이름은 소문자로 작성하기
- 패키지 이름은 예약어 사용 금지
- 클래스 패스(classpath)
- 클래스 파일의 위치를 알려줌
- JVM이 프로그램 실행 시, 클래스패스를 통해 클래스 파일을 찾음 -> 편하게 패키지에 import 할 수 있음
- CLASSPATH 환경변수를 쓰는 이유
- CLASSPATH : JAVA_HOME
- java는 JVM을 통해 다른 폴더에서도 실행 가능하지만,
java의 컴파일러인 javac는 path를 잡지않으면 (경로를 정해주지 않으면) 실행 불가능 - JAVA_HOME : java에서 읽어오는 환경변수
- 자바 버전, 설치한 위치가 바뀌었을 때, 변수값만 바꾸어주면
- 자바 명령어를 그대로 이용 가능하기 때문에 사용
import문
- import 패키지명.클래스명;
- import 패키지명.*
- ctrl+shift+O : 자동입력
- java.lang 패키지의 클래스는 따로 import 안해도 됨
- String, Object … (자주 쓰는것들이라)
- static import문을 쓰면 클래스 이름을 생략 가능함
- import static java.lang.System.out; //System.out을 out만 써도 됨.
- 사용하고자 하는 클래스 등이 다른 패키지에 있다면,
- import문으로 가져와야 한다
접근 제어자
final
- (값이나) 변경/확장될 수 없는 클래스/메서드/변수
- 오버라이딩/상속도 안됨
abstract
- 추상 메서드/클래스
- 선언부 O, 구현부 X
static
- 모든 객체에 공통적으로 사용되는 변수
- 객체를 생성하지 않아도 호출 가능
- 전역에서 공통적으로 쓸 메서드/변수 일 때 붙이면 좋다
주의할 점
- 클래스
- abstract와 final을 동시에 사용할 수 없다
- 메서드
- abstract 앞에 static, private는 함께 사용할 수 없다
- private와 final 중 하나만 사용한다
로컬 클래스
- 메서드 내의 클래스.
- public 등의 접근제한자나 static 을 붙일 수 없다
멤버 클래스
- 클래스 내에 중첩된 static 클래스 안에있는 필드들은 그 바깥 클래스의 static 필드/메서드만 접근 가능
- 바깥 클래스의 인스턴스 필드/메서드는 접근 불가능하다
추상 클래스
- {}이 없거나, {}안에 아무것도 없는 미완성 메서드를 가진 클래스
- 구현되기 전엔 객체를 생성할수없다
- 상속을 통해 구현부를 완성해야 클래스의 참조변수 생성 가능
- 보통 클래스들의 공통부분을 모아 선언하는편
인터페이스
- 추상메서드의 집합 (추상메서드, 상수만 가짐)
- 생성자는 가질 수 없다
- 추상메서드는 선언부만 존재 ({}이 없음)
- public abstract 가 자동적으로 붙게됨 (생략해도)
- 코드 변경 없이, 연결된 객체들을 다양하게 변경하기 위해 사용
- public interface 인터페이스명 {...}
- 코드를 입력하면, 인터페이스를 통해 객체의 메서드들을 호출해줌
- 모든 멤버(변수,메서드)가 public
- public static final 반환타입 상수이름(대문자)
- 상속과 구현이 둘다 가능
- class A extends B implements C {...} 일 때,
- A는 B,C가 조상이다
- 디폴트, static 메서드 가능 (JDK 1.8 부터)
- 선언하고, 구현에 실행내용까지 작성함
- public 특성을 가짐 (생략하더라도 컴파일 과정에서 붙게됨)
- 디폴트 메서드는 인스턴스 메서드라서 외부에서는 인터페이스 객체를 선언해야 호출이 가능
- 추상메서드보다 좋은 점 : 클래스랑 연결되어있다면, 추상메서드를 만들면 또 구현해줄 실체 메서드를 그 클래스에 추가해야된다는 점이 복잡한데, 디폴트 메서드는 따로 추가하지 않아도 됨
- 단순히 상속만 받기(호출용) / 재정의해서 내용 변경하기 / 추상 메서드로 재선언하기 <<3가지 기능!
- 클래스 내에서 추상메서드로 재선언하면 그 메서드는 실체메서드도 갖고있어야 함
//인터페이스에 연결되있는 전제하에
RemoteControl rc = null; //인터페이스 변수 선언
//Tv객체에 rc 인터페이스 대입
//인터페이스를 통해 호출
rc = new Tv();
rc.turnOn();
rc.turnOff();
rc = new Audio();
rc.turnOn();
rc.turnOff();
중첩 인터페이스
- 클래스의 멤버로 선언된 인터페이스
내부 클래스
- 외부클래스의 지역변수는 final이 붙은 상수만 존재한다
- 인스턴스 내부클래스는 외부클래스의 private 멤버에 접근 가능
익명 클래스
- 이름이 없는 일회용 클래스. 정의와 생성을 동시에 함
- 재사용 가능성 X , 이벤트성 용도, 확장할 시 유지보수 불리할때 사용
- 클래스 내에 메서드가 많거나 코드가 길어지면 오히려 가독성이 떨어져 안쓰는 것이 좋다.
- 소스파일을 만들지 않고도 구현 객체를 만들수 있는 방법
//익명 클래스
new 조상클래스이름() {
//멤버선언
};
조상클래스이름 참조변수 = new 조상클래스이름() {
//멤버선언
};
//익명 구현클래스
new 구현인터페이스이름() {
//멤버선언
};
//익명클래스 implements 구현인터페이스 .. 이런형식일때
어노테이션
- 주석처럼 프로그래밍 언어에 영향을 미치지 않음
- @Override 메서드가 오버라이드 됬음을 알려줌. 코드 문법 에러를 체크함
'Java' 카테고리의 다른 글
[Java] 제네릭스 (0) | 2022.06.25 |
---|---|
[Java] 예외, 래퍼 클래스 (0) | 2022.06.25 |
[Java] 스레드 (0) | 2022.06.21 |
[Java] Object, String 클래스 (0) | 2022.06.21 |
[Java] 조건문, 클래스, 메서드 (0) | 2022.06.19 |