제너릭(Generic) 학습 전 이 전 배웠던 클래스 캐스팅(추상화 및 다형성) 에 대해 복습을 먼저 진행한다.
<복습>
1. 상속
- 부모클래스의 속성과 기능을 그대로 이어받아 사용할 수 있게하고 기능의 일부분을 변경해야 할 경우 상속받은 자식클래스에서 해당 기능만 다시 수정(정의)하여 사용할 수 있게 하는 것
- 적은 양의 코드로 새로운 클래스 작성 가능
- 코드를 공통적으로 관리할 수 있어 코드의 추가 및 변경 용이
- 자식클래스에서 해당 기능을 다시 수정해 사용할 수 있게 하는 데서 오버라이딩(다형성)이 활용
2. 다형성
- 하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것
- 오버라이딩(Overriding): 부모클래스의 메서드와 같은 이름, 매개변수를 재정의 하는 것
- 오버로딩(Overloading): 같은 이름의 함수를 여러개 정의하고, 매개변수의 타입과 개수를 다르게 하여 매개 변수에 따라 다르게 호출할 수 있게 하는 것
3. 추상화
- 추상화란, 공통된 특징을 묶어 하나의 클래스로 정의하는 것을 말한다.
4. 추상클래스
- 여러 클래스간 비슷한 필드와 메서드를 공통적으로 추출해 만들어진 클래스
5. 추상메소드
- 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드를 의미한다. 자바에서 추상 메소드를 선언하여 사용하는 목적은 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함이다.
- abstract키워드를 메소드 앞에 붙여준다.
- 추상 메소드는 추상 클래스 안에서 선언만하고, 실질적인 메소드의 추상클래스를 상속받은 일반 자녀클래스에서 진행한다.
- 추상메소드 뒤에 '{}'가 아닌 ';'을 붙인다.
5. 추상클래스 및 인터페이스
- 상속 관계: '~는 ~이다.' == (is -a)
- 포함 관계: '~는 ~을 가지고 있다.' == (has -a)
6. 캐스팅 형변환 (클래스의 형변환)
- 단순히 한 데이터 타입으로 변환하는데 사용되는 기술
- 상위 클래스로 변수를 선언하고, 하위클래스의 생성자로 인스턴스 생성
- 상속관계에서 모든 하위 클래스는 하위 클래스로 형 변환 가능/ 역은 안됨
* 업타운 캐스팅
-> Super타입 클래스: 부모클래스 상속
-> Sup타입 클래스: 부모로부터 상속받은 하위 클래스
- 업(Up) 캐스팅: 서브타입의 인스턴스를 수퍼 타입의 변수로 접근하는 것을 말한다. 자식 클래스가 부모 클래스 타입으로 캐스팅 되는것을 뜻한다. (자동 형변환)
- 다운(Down) 캐스팅: 서브타입 인스턴스를 참조하는 수퍼타입 변수를 재참조하는 것을 말한다. 부모 클래스가 자식클래스 타입으로 캐스팅되는 것을 뜻한다. (강제 형변환)
Java OOP 객체지향(2): 추상화, 인터페이스, 다형성, 쓰레드, 형 변환
📌 1. 추상화(Abstraction) 📎 추상화란? > 추상화란, 공통된 특징을 묶어 하나의 클래스로 정의하는 것을 말한다.예를들어, 람보르기니와 페라리 2대의 차를 보았을때 각 차에는 핸들, 바퀴, 문, 창
velog.io
예제 01.
package casting;
class Person{ //추상화 ->student , employee
String name;
}
class Student extends Person {
// String name;
}// 학생
class Employee extends Person {
// String name;
}// 회사원
public class CastiongTest01 {
public static void main(String[] args) {
// IS-A
// 사람 > 학생
Person p1 = new Student(); //다형성
Person p2 = new Employee(); //다형성
// 학생 < 사람
Student s1=(Student) p1;
// Student s2=(Student) p2; -> 강제캐스팅 오류 낼 수 있음
}
}
예제 02.
package casting;
public class Person {
String name;
public Person(String name) {
this.name =name;
}
public Person() {
}
}
package casting;
public class Employee extends Person{
int empNo;
public Employee(String name) {
super(name); // 슈퍼의 기본생성자
}
public Employee() {
}
}
package casting;
public class Student extends Person{
int stdNo;
public Student(String name, int stdNo) {
super(name); //항상 첫번째에 위치
this.stdNo = stdNo;
}
public Student() {
}
}
main>
package casting;
import java.util.ArrayList;
import java.util.Vector;
public class CastingTest02 {
public static void main(String[] args) {
// 데이터타입에 상관없이 모든 타입 삽입 가능
ArrayList list = new ArrayList();
list.add(new Student());
list.add(new Employee());
list.add(10); // 아래 캐스팅을 하기에 애매한 부분
/*
* for(int i=0; i<list.size(); i++) {
* Person s= (Person) list.get(i);
* System.out.println(s.name);
* }
*/
Vector list2= new Vector();
//Object obj = new Student("노그린", 1);
list2.add(new Student("노그린", 1));
list2.add(new Student("노블루", 2));
list2.add(new Student("노레드", 3));
// list 에 동일한 데이터만 저장했더니 출력 시 일괄처리가 가능
// 그래도 저장할때는 Object에 다형적표현으로 저장되기에,
// 읽어올땐 해당하는 객체로 캐스팅 필요
for(int i=0; i<list2.size(); i++) {
Student std=(Student) list2.get(i);// Student에 저장해야함 //데이터 타입에 따라
System.out.println(std.stdNo + " : "+ std.name);
}
}
}
예제 02>
package casting;
import java.util.ArrayList;
public class CastingTest03 {
public static void main(String[] args) {
// 마치 배열 처럼 특정한 데이터 타입만 넣는
// list 선안 시 반영
// 제네릭 표현 , 집합에는 스튜던트만 넣을 겁니다.
ArrayList<Student> list = new ArrayList<>();
// ==ArrayList<Student> list = new ArrayList<Student>();
// Student[] ;
list.add(new Student("홍길동",1));
list.add(new Student("이길동",2));
list.add(new Student("삼길동",3));
// list.add(new Employee("aaa"));
// list.add(1);
// 제네릭에 지정한 타입 이외는 허용하지 않습니다. ---> 컴파일러가 체크
// 제니릭을 규현해서 데이터를 일괄처리하였더니,
// 읽어올때 캐스팅 필요하지 않음
for(int i=0; i<list.size(); i++) {
Student std = list.get(i);
System.out.println(std.stdNo + " : "+std.name);
}
}
}
예제 03>
package generic;
public class Box {
private Object obj;
public void add(Object obj) {
obj = obj ;
}
public Object get() {
return obj;
}
}
package generic;
import casting.Student;
public class BoxTest01 {
public static void main(String[] args) {
Box box = new Box ();
box.add(new Student());
//Object obj = new Student();
Student std = (Student) box.get();
System.out.println();
box.add(new String("문자열"));
// Object obj = new String("문자열");
String str= (String) box.get();
}
}
1. 제네릭(Generic)
01. 정의:
제네릭(Generic)은 직역하자면 '일반적인'이라는 뜻으로, '데이터 형식에 의존하지 않고, 하나의 값이 여러 다른 데이터 타입들을 가질 수 있도록 하는 방법'이다.
ArrayList 및 LinkedList 타입 지정할때는
객체<타입> 객체명 = new 객체<타입>(); 으로 <> 괄호 안에 들어가는 타입을 지정해준다.
|
ArrayList<Integer> list1 = new ArrayList<Integer>(); |
|
ArrayList<String> list2 = new ArrayList<Integer>(); |
|
LinkedList<Double> list3 = new LinkedList<Double>(): |
|
LinkedList<Character> list4 = new LinkedList<Character>(); |
이때, 어떤 자료를 String 타입도 지원하고싶고 Integer 타입 등 많은 지원하고 싶을 때 제네릭이라는 것을 사용한다.
--> 즉 제네릭(Generic)은 클래스 내부에서 지정하는 것이 아닌 외부에서 사용자에 의해 지정되는 것을 의미한다.
한마디로 특정(Specific) 타입을 미리 지정해주는 것이 아닌 필요에 의해 지정할 수 있도록 하는 일반(Generic) 타입이라는 것이다.
02. Generic의 장점
(1) 제네릭을 사용하면 잘못된 타입이 들어올 수 있는 것을 컴파일 단계에서 방지할 수 있다.
(2) 클래스 외부에서 타입을 지정해주기 때문에 따로 타입을 체크하고 변환해줄 필요가 없다(캐스팅할 필요가 없다). 즉, 관리하기가 편하다.
(3) 비슷한 기능을 지원하는 경우 코드의 재사용성이 높아진다.
03. Generic 주요 기능
(1) 저장 시 컴파일러 타입 체크를 해준다.
(2) read 시 캐스팅이 필요치 않다.
예제 01>
package generic;
public class Box {
private Object obj;
public void add(Object obj) {
obj = obj ;
}
public Object get() {
return obj;
}
}
package generic;
import casting.Student;
public class BoxTest01 {
public static void main(String[] args) {
Box box = new Box ();
box.add(new Student());
//Object obj = new Student();
Student std = (Student) box.get();
System.out.println();
box.add(new String("문자열"));
// Object obj = new String("문자열");
String str= (String) box.get();
}
}
예제 02.
package generic;
// 제네릭 타입
// 클래스 또는 인터페이스 이름 뒤에 <> 안쪽에 타입을 대신하여 타입파라미터 표현
// 일반적으로 타입파라미터는 대문자 한글자 표기
// 제네릭으로 정의한 클래스 : 현재 T의 데이터 타입은 아직 결정 되지 않았음
public class Case<T /*, V*/ > { // T, V 와 같이 멀티형도 가능
private T name;
public void setName(T name) {
this.name= name;
}
public T getName() {
return name;
}
}
package generic;
public class GenericTest01 {
public static void main(String[] args) {
Case<String> ca = new Case<>(); // case 클래스의 타입은 String 이 됨
// 즉 T = String
ca.setName("이름");
ca.getName();
System.out.println();
}
}
'JAVA _기초' 카테고리의 다른 글
[JAVA] 콜렉션(Collection) (0) | 2023.02.27 |
---|---|
[JAVA] Inheritance : 상속_03 (0) | 2023.02.23 |
[JAVA] Inheritance : 상속_02 (0) | 2023.02.22 |
[JAVA] Inheritance : 상속 _01 (0) | 2023.02.21 |
[JAVA] Exceptions: 예외 (0) | 2023.02.20 |