모든 클래스의 부모 (생략되어 있다.)
1. Object 타입 일치
타입 일치. Instanceof. 다운 캐스팅
package ex17;
// Dog 클래스: 강아지를 나타내는 클래스
class Dog {
String name = "강아지"; // 강아지의 이름
}
// Cat 클래스: 고양이를 나타내는 클래스
class Cat {
String name = "고양이"; // 고양이의 이름
}
// 타입 일치
public class ob01 {
// Object 타입으로 들어오는 매개변수 u의 타입을 확인하고 해당 타입에 맞게 처리하는 메서드
static void callName(Object u) {
// u가 Dog 객체일 경우
if (u instanceof Dog) {
// 다운 캐스팅: Object 타입을 Dog 타입으로 변환
Dog d = (Dog) u;
System.out.println(d.name); // 강아지의 이름을 출력
}
// u가 Cat 객체일 경우
else if (u instanceof Cat) {
// 다운 캐스팅: Object 타입을 Cat 타입으로 변환
Cat c = (Cat) u;
System.out.println(c.name); // 고양이의 이름을 출력
}
}
public static void main(String[] args) {
// Dog 객체를 전달
callName(new Dog()); // "강아지" 출력
// Cat 객체를 전달
callName(new Cat()); // "고양이" 출력
}
}
2. 제네릭 기본기
new 할 때 타입을 결정할 수 있다.
package ex17;
// 제네릭을 사용한 Box 클래스
class Box<T> {
T data; // T의 타입은 Box 객체를 생성할 때 결정됨
}
public class Ge01 {
public static void main(String[] args) {
// Box<String>은 String 타입만을 받을 수 있는 Box 객체
Box<String> b = new Box(); // <String>으로 타입을 지정
b.data = "Hello"; // String 타입의 데이터를 저장
// Box<Integer>는 Integer 타입만을 받을 수 있는 Box 객체
Box<Integer> i = new Box(); // <Integer>로 타입을 지정
i.data = 10; // Integer 타입의 데이터를 저장
}
}
3. 오브젝트로 저장하든, 제네릭으로 저정하든 무슨 차이가 있는 거지 ?
package ex17;
// 제네릭을 사용한 클래스
class ACom<T> {
// 제네릭 타입 T로 데이터를 저장하는 메서드
void save(T data) {
System.out.println(data + "가 저장되었습니다.");
}
}
// Object 타입을 사용하는 클래스
class BCom {
// Object 타입으로 데이터를 저장하는 메서드
void save(Object data) {
System.out.println(data + "가 저장되었습니다.");
}
}
// 타입 일치? 동적 바인딩이 더 좋은 거 아닌가 ?
// 1. Object를 쓸 수 밖에 없는 경우
// 2. Generic을 써야되는 경우 (무조건 제네릭으로 저장하는게 유리하다.)
public class Ob02 {
public static void main(String[] args) {
// ACom<String>은 String 타입만 받는 제네릭 클래스
ACom<String> ac = new ACom();
ac.save("문자열"); // 문자열을 저장
// BCom은 Object 타입을 받아서 어떤 타입의 데이터든 저장할 수 있음
BCom bc = new BCom();
bc.save(1); // 숫자 1을 저장
}
}
4. 데이터 저장은 제네릭이 무조건 유리하다.
new 할 수 있다면 !!
package ex17;
// Teacher 클래스: 선생님 정보를 담는 클래스
class Teacher extends Object {
private String name = "선생님"; // 선생님의 이름
// 선생님의 이름을 반환하는 메서드
public String getName() {
return name;
}
}
// Student 클래스: 학생 정보를 담는 클래스
class Student extends Object {
private String name = "학생"; // 학생의 이름
// 학생의 이름을 반환하는 메서드
public String getName() {
return name;
}
}
// FCom 클래스: Object 타입으로 데이터를 저장하는 클래스 (제네릭 사용 안 함)
class FCom {
Object data; // 데이터를 저장할 변수
// 데이터를 저장하는 메서드
void save(Object u) {
data = u; // 데이터를 Object 타입으로 저장
}
}
// KCom 클래스: 제네릭을 사용하여 데이터 타입을 지정할 수 있는 클래스
class KCom<T> {
T data; // 데이터를 저장할 변수 (제네릭 타입 T)
// 데이터를 저장하는 메서드
void save(T u) {
data = u; // 데이터를 제네릭 타입 T로 저장
}
}
// 제네릭 사용 예시
public class Ge02 {
public static void main(String[] args) {
// FCom 사용 예시 (제네릭 사용하지 않음)
FCom f1 = new FCom();
f1.save(new Teacher()); // Teacher 객체 저장
// FCom에서 데이터를 꺼낼 때 다운 캐스팅 필요
Teacher t1 = (Teacher) f1.data; // Object 타입에서 Teacher로 다운 캐스팅
System.out.println(t1.getName()); // "선생님" 출력
// KCom 사용 예시 (제네릭 사용)
KCom<Student> k1 = new KCom(); // Student 타입으로 KCom 객체 생성
k1.save(new Student()); // Student 객체 저장
// KCom에서 데이터를 꺼낼 때 다운 캐스팅 필요 없음
System.out.println(k1.data.getName()); // "학생" 출력
}
}
5. new 할 수 없다면, 오브젝트로 저장
가령 싱글톤 패던일 때 !
미리 클래스를 메모리에 올려놔야 할 때, 무슨 타입이 들어올 지 모르겠으면,
오브젝트 타입으로 저장한다.
package ex17;
class Banana extends Object {
private String name = "바나나";
// 바나나 이름을 반환하는 메서드
public String getName() {
return name;
}
}
class Apple extends Object {
private String name = "사과";
// 사과 이름을 반환하는 메서드
public String getName() {
return name;
}
}
// 저장소 -> 한개만 !! (싱글톤 패턴)
class Session {
// Session 객체는 딱 하나만 존재해야 하므로 static으로 선언
private static Session session = new Session();
// 생성자를 private로 선언하여 외부에서 Session 객체를 만들 수 없게 막음
private Session() {
}
// Session 객체를 반환하는 메서드 (싱글톤 패턴)
public static Session getSession() {
return session;
}
// attribute는 Session에 담을 수 있는 속성 (객체)
private Object attribute; // 속성 Property
// 객체를 Session에 담는 메서드 (attribute에 값을 넣음)
public void setAttribute(Object attribute) {
this.attribute = attribute; // attribute에 값을 저장
}
// Session에 담긴 객체를 반환하는 메서드
public Object getAttribute() {
return attribute; // attribute에 담긴 값을 반환
}
}
public class Ob03 {
public static void main(String[] args) {
// Session 객체를 가져옴 (싱글톤 패턴)
Session session = Session.getSession();
// 바나나 객체를 Session에 담음
session.setAttribute(new Banana());
// Session에서 바나나 객체를 꺼냄 (Object 타입으로 반환)
Banana banana = (Banana) session.getAttribute(); // 다운 캐스팅: Object 타입을 Banana 타입으로 변환
System.out.println(banana.getName()); // "바나나" 출력
// 사과 객체를 Session에 담음
session.setAttribute(new Apple());
// Session에서 사과 객체를 꺼냄 (Object 타입으로 반환)
Apple apple = (Apple) session.getAttribute(); // 다운 캐스팅: Object 타입을 Apple 타입으로 변환
System.out.println(apple.getName()); // "사과" 출력
}
}
Share article