이번 주차 학습 내용은 상속 개념이 강한 class, interface, 그리고 generics에 대해 기본적인 학습을 하고자 한다.
그 전의 이전의 학습한 내용을 정리하면 자바 특징은 다음과 같다.
지난 번 학습한 객체 지향 언어에서의 SOLID 원칙에 따라 자바 내 모든 코드는 반드시 클래스 내 존재해야 한다.
1. [] : 배열을 의미하는 기호, 배열의 타입, 이름 옆에 붙일 수 있음.
2. {} : 시작과 끝을 의미하며 괄호 내 작업 내용 작성
3. main 메서드를 가진 클래스가 하나 이상 있어야 하며 java.exe를 통해 app 실행
4. 하나의 클래스에는 하나의 public class만 존재 가능, publoc class는 java파일과 동일한 이름을 가져야 함.메소드 선언 방식 : 접근제한자 / 반환형 / 메소드명 / 매개변수
- 접근제한자 : 주로 publoc, 속성은 주로 private 선언, 이외의 default, protected 등
- 반환형 : 리턴값 여부 (void : 리턴 X)
- 메소드명 : 함수명을 의미
- 매개변수 : 소괄호 내 들어갈 변수 타입, 변수 지정
클래스의 묶음이 바로 패키지이며 import 패키지 를 통해 클래스 사용!
즉 class 생성 순서, 기본구조는 다음과 같다// 1. 패키지명 선언 package com.practice.object // 2. 클래스 선언 public class 클래스명 { // 3. 속성값 (변수 선언) : 접근제한자 / 예약어 / 자료형 변수명 private int age; private String name; // 4. 생성자 정의 // 4-1. 기본 생성자 - 객체 생성 위한 메서드, 매개변수 생성자 - 객체 생성, 필드 초기화 public 생성자명 () {} Public 생성자명(매개변수) { } // 5. 메서드 (기능) 정의 : 접근제한자 / 반환형 / 메서드명 (매개변수) {기능정의} public void 메소드명() { } public String 메서드명() { Return string 값 ; } }
인터페이스는 추상 메서드만 가질 수 있고, 구현 메서드는 가질 수 없는 일종의 추상 클래스
즉, 인터페이스는 서로 다른 기능을 하는 클래스들을 묶을 때 사용한다.
또한, 상위 클래스가 인터페이스인 경우, 하위 클래스가 무조건 구현되어야 하므로 100% 다형성을 보장한다.
인터페이스 내 변수는 public static final 로만 지정가능하며 생략이 가능하다.
다중 상속 역시 가능해 상위 클래스가 인터페이스인 경우 하위 클래스는 인터페이스를 여러 개 상속 받을 수 있다
-> public class 클래스명 implements 인터페이스1, 인터페이스2 ...즉 인터페이스 특징을 정리하면 다음과 같다.
1. 다중 상속 가능 (1개의 하위 클래스는 여러 상위 클래스들을 상속 받을 수 있다)
2. 추상 메서드만 보유
3. 생성자 생성 불가.
4. 메서드 오버라이딩 필수. (상위 클래스의 함수를 모두 오버라이딩 처리)
예제 코드는 다음과 같다.
- 상위 클래스 : Company
- 하위 클래스 : GameCompany, DesignCompany
public interface Company {
public String parentCompanyName = "상위 클래스 회사";
public void makeProduct();
}
public class DesignCompany implements Company {
private String CompanyName;
DesignCompany(String CompanyName) {
this.CompanyName = CompanyName;
}
@Override
public void makeProduct() {
System.out.println("design product");
}
}
// 상위 추상 클래스를 반드시 오버라이딩 처리.
public class GameCompany implements Company {
String ComName;
GameCompany(String CompanyName) {
this.ComName = CompanyName;
}
public void makeProgram() {
System.out.println("make A program");
}
@Override
public void makeProduct() {
System.out.println("A product");
}
}
java에서 Generics란, 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다. (꺽쇠 괄호(다이아몬드 연산자)로 표현하며 괄호 내 타입명 기재되어 list내에는 문자열 데이터만 적재.)
ArrayList<String> list = new ArrayList<>();
즉 아래 그림과 같다고 보면 된다.
-> 이처럼 Generics는 배열의 타입을 지정하듯 클래스 및 메서드에서 사용할 내부 데이터 타입을 파라미터 주듯이 외부에서 지정하는 방식으로 타입을 변수화 한 기능이라고 이해하면 된다.🎈 Generics Type parameter
// 타입 파라미터 class FruitBox<T> { List<T> fruits = new ArrayList<>(); public void add(T fruit) { fruits.add(fruit); } } // Generic 타입 매개변수에 정수, 실수, 문자열 타입 할당 FruitBox<Integer> intBox = new FruitBox<>(); FruitBox<Double> intBox = new FruitBox<>(); FruitBox<String> intBox = new FruitBox<>(); // 클래스도 가능 FruitBox<클래스명> intBox = new FruitBox<클래스명>();
-> Generics에서 할당 받을 수 있는 타입은 Reference 타입 뿐. 즉 int, double 등은 X
🎈 Generic 사용 이유, 이점
- 컴파일 타임에 타입 검사를 통해 예외 방지 가능.
- 불필요한 캐스팅(형 변환)을 없애 성능 향상 가능 (캐스팅에 들어가는 메모리 감소, 가독성 올라감)
-> 주의 사항 역시 존재!
- generic 타입의 객체는 생성 X
- static 멤버에 generic 타입 x
- generic 배열 선언 주의해야 하고, 타입 배열 선언 이후 다른 타입 하는 경우 저장 X
// generic 클래스 생성
class Sample<T> {
private T value; // 멤버 변수 val의 타입은 T 이다.
// T 타입의 값 val을 반환한다.
public T getValue() {
return value;
}
// T 타입의 값을 멤버 변수 val에 대입한다.
public void setValue(T value) {
this.value = value;
}
}
public static void main(String[] args) {
// 정수형을 다루는 제네릭 클래스
Sample<Integer> s1 = new Sample<>();
s1.setValue(1);
// 실수형을 다루는 제네릭 클래스
Sample<Double> s2 = new Sample<>();
s2.setValue(1.0);
// 문자열을 다루는 제네릭 클래스
Sample<String> s3 = new Sample<>();
s3.setValue("1");
}
-> 인터페이스도 적용 가능
단, @Override는 필수!
generics 관련 추가 학습 자료
generics
UML, 클래스 다이어그램 학습
UML, 클래스 다이어그램