1. 추상 클래스 (확장의 개념)
- abstract 클래스는 상속 전용의 클래스
- 구현의 강제를 통해 프로그램의 안전성 향상
- 메서드의 선언부만 남기고 구현부는 세미콜론(;)으로 대체
- 구현부가 없다는 의미로 abstract 키워드를 메서드 선언부에 추가
- 객체를 생성할 수 없는 클래스라는 의미로 클래스 선언부에 abstract를 추가
※ Vehicle v = new DiselSuv(); 와 같이 하위 클래스의 객체 생성은 가능
- 반드시 자식 클래스에서는 추상 메서드를 오버라이딩 해야된다.
package com.ssafy.day5.a_abstract;
// 추상 클래스 (한개라도 추상 메서드가 있으면 추상클래스가 된다.)
public abstract class Vehicle {
private int curX, curY;
public void reportPosition() {
System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
}
// 추상 메서드 >> 반드시 자식 클래스에서 오버라이딩 해야된다
public abstract void addFuel();
}
2. Interface (공통 기능을 목적에 맞게 명세의 개념)
- 최고 수준의 추상화 단계 : 일반 메서드는 모두 abstract 형태
- JDK 8에서부터 default method와 static method 추가
- 클래스와 유사하게 interface 선언
- "모든 멤버변수는 public static final이며 생략 가능" >> 상속받지 못한다
- 모든 메서드는 public abstract이며 생략 가능
- 인터페이스는 다중 상속(extends)이 가능
- 클래스에서 implements 키워드를 사용해서 interface 구현 >> 모든 메서드를 오버라이딩 하거나 구현하지 않을 경우 abstract 클래스로 표시해야 함.
- 인터페이스와의 관계도 is a 관계이지만 좀 더 세부적으로 is able to라고도 한다. (ex. Object o = new IronMan();)
- 인터페이스 간 상속 시 오버라이딩 필요 X, 하지만 클래스에서 implements시 오버라이딩 필요 O
- 객체 생성 X
3. 인터페이스 필요성
- 구현의 강제로 표준화 처리
- 인터페이스를 통한 간접적인 클래스 사용으로 손쉬운 모듈 교체 지원
- 서로 상속의 관계가 없는 클래스들에게 인터페이스를 통한 관계 부여로 다형성 확장
- 모듈 간 독립적 프로그래밍 가능 > 개발 기간 단축
4. default method
- 인터페이스에 선언 된 구현부가 있는 메서드
- default 제한자 추가 후 메서드 구현부 작성
- 인터페이스를 수정 시 모든 구현체들이 오버라이딩을 해야함 > default를 작성하면 구현 해야 할 필요가 없어짐
- 추상 클래스를 사용하다가 요즘은 인터페이스와 default method를 사용하는 추세
- 부모 인터페이스와 부모 클래스와의 default method 충돌 시 super class가 우선
- 인터페이스에서 default method를 제공하고 다른 인터페이스에서도 같은 이름의 메서드가 있을 경우 sub 클래스는 반드시 오버라이드 해서 충돌 해결
5. 추상 클래스와 인터페이스
6. generic
- 미리 사용할 타입을 명시해서 형 변환을 하지 않아도 되게 함.
- userNormalBox와 같이 사용할 경우는 사용시 마다 입력된 타입으로 형 변환을 해야한다.
- generic을 사용하면 객체의 타입에 대한 안전성 향상 및 형 변환의 번거러움 감소
- 타입 파라미터 > T : reference Type, E : Element, K : Key, V : Value
public class NormalBox {
private Object some;
public Object getSome() {
return some;
}
public void setSome(Object some) {
this.some = some;
}
}
public class GenericBox<T> {
private T some;
public T getSome() {
return some;
}
public void setSome(T some) {
this.some = some;
}
}
private static void useNormalBox() {
// TODO: NormalBox 타입의 객체를 생성하고 사용해보세요.
NormalBox box = new NormalBox();
box.setSome("Hello");
Object some = box.getSome();
if (some instanceof String data) {
data = (String)data;
System.out.println("data : " + data);
}
// END
}
private static void useGenericBox() {
// TODO: GenericBox 타입의 객체를 생성하고 사용해보세요.
GenericBox<String> box = new GenericBox<>();
box.setSome("hello");
String data = box.getSome();
System.out.println(data);
// END
}
- generic 메서드
※ 객체 생성 시점에 T의 타입 결정, 메서드 호출 시점에 P의 타입 결정
public <P> void method1(P p) {
System.out.printf("클래스 레벨의 T: %s%n", some.getClass().getSimpleName());
System.out.printf("파라미터 레벨의 P: %s%n", p.getClass().getSimpleName());
}
tpmt.method1(10);
7. type parameter 제한
- extends 키워드를 사용하여 Number 클래스를 상속받는 클래스만 사용 가능
(ex. NumberBox<String> box = new NumberBox<>();) >> 오류 발생
public class NumberBox<T extends Number> {
private T some;
public T getSome() {
return some;
}
public void setSome(T some) {
this.some = some;
}
}
8. Generic Type 객체를 할당 받을 때 와일드 카드(?) 이용
- 제네릭은 형변환이 되지 않는다.
PersonBox<Person> pPer2 = new PersonBox<SpiderMan>(); // 불가능
- 객체를 할당 받을 때 와일드 카드를 이용하면 형 변환 처럼 사용이 가능하다. (type parameter은 다르다.)
- type parameter는 ?가 불가능 하다.
public class WildTypeTest {
@SuppressWarnings("unused")
public void wildCardTest() {
PersonBox<Object> pObj = new PersonBox<>();
PersonBox<Person> pPer = new PersonBox<>();
PersonBox<SpiderMan> pSpi = new PersonBox<>();
// 어떤 타입이 오던지 다 받아줄 수 있다.
PersonBox<?> pAll = pPer;
pAll = pSpi;
pAll = pObj;
// Person 또는 상속받은 경우만 받아줄 수 있다.
PersonBox<? extends Person> pChildPer = pPer;
pChildPer = pSpi;
// pChildPer = pObj;
// Person 또는 조상만 받아줄 수 있다.
PersonBox<? super Person> pSuperPer = pPer;
// pSuperPer = pSpi;
pSuperPer = pObj;
}
}
class Person {
}
class SpiderMan extends Person {
}
class PersonBox<T> {
}
'Web > JAVA' 카테고리의 다른 글
Collection, lamda (1) | 2024.01.23 |
---|---|
예외 처리(exception handling) (0) | 2024.01.22 |
데이터 은닉(Encapsulation), 다형성(Polymorphism), Singleton (0) | 2024.01.18 |
상속(Inheritance), overriding, package, import, 제한자 (0) | 2024.01.17 |
클래스, 객체, 메서드, 변수, 생성자 (0) | 2024.01.16 |