public class Ex95_Casting
{
public static void main(String[] args)
{
//Ex95_Casting.java
//1.업캐스팅
// - 자식 -> 부모
Parent p1;
Child c1;
c1 = new Child(); //자식객체생성
p1 = (Parent)c1; //가능 "c1앞에 (parent)"생략 가능
System.out.println(p1.n);
p1.test();
/*
Parent p = new Parent();
System.out.println(p.n);
p.test();
*/
//2.다운캐스팅
// - 부모 -> 자식
Parent p2;
Child c2;
p2 = new Parent(); //부모객체 생성
//** 100% 불가능
// c2 = (Child)p2; //Child = Parent
//3. 다운캐스팅
Parent p3;
Child c3;
Child c4 = new Child();
p3 = (Parent)c4; //Parent = Child //업캐스팅 : 가능
c3 = (Child)p3; //Child = Parent //다운캐스팅 : 가능
System.out.println(c3.n);
System.out.println(c3.m);
c3.test();
c3.test2();
}
}
class Parent
{
public int n = 10;
public void test() {
System.out.println("부모메서드 test()");
}
}
class Child extends Parent {
public int m = 20;
public void test2() {
System.out.println("자식메서드 test2()");
}
}
Up Casting & Down Casting 활용
import java.util.*;
public class Ex97_Casting
{
public static void main(String[] args)
{
//Ex97_Casting.java
// 프린터 대리점 운영
// 1. 매달 1회 모든 제품을 작동 테스트
// 2. 재고 HP640 x 5대
// LG550 x 3대
m3(); // 가장 효율적인 방법(업캐스팅 이용)
}//end main
//case 1. 각각의 객체로 처리
public static void m1() {
HP640 hp1 = new HP640();
HP640 hp2 = new HP640();
HP640 hp3 = new HP640();
HP640 hp4 = new HP640();
HP640 hp5 = new HP640();
LG550 lg1 = new LG550();
LG550 lg2 = new LG550();
LG550 lg3 = new LG550();
//한달 -> 점검
hp1.print();
hp2.print();
hp3.print();
hp4.print();
hp5.print();
lg1.print();
lg2.print();
lg3.print();
}//end m1()
//case 2. 배열을 이용하여 처리
public static void m2() {
HP640[] hps = new HP640[5];
for(int i=0; i< hps.length; i++) {
hps[i] = new HP640();
}
LG550[] lgs = new LG550[3];
for(int i=0; i< lgs.length; i++) {
lgs[i] = new LG550(); //인스턴스
}
//1달에 1번 체크
for(int i=0; i< hps.length; i++) {
hps[i].print();
}
for(int i=0; i< lgs.length; i++) {
lgs[i].print();
}
}//end m2()
//case 3.
public static void m3() {
//업캐스팅
//Printer p = new Printer(); //객체생성X
//추상클래스나 인터페이스는 스스로 인스턴스를 만들지못하지만
// 참조변수는 생성할 수 있다.
/*
Printer p1 = new HP640(); //가능
Printer p2 = new LG550(); //가능
Object p3 = new HP640(); //가능
Object p4 = new LG550(); //가능
*/
Printer[] list = new Printer[8];
list[0] = new HP640();
list[1] = new HP640();
list[2] = new HP640();
list[3] = new HP640();
list[4] = new HP640();
list[5] = new LG550();
list[6] = new LG550();
list[7] = new LG550();
//1달에 1번 출력
for(int i=0; i< list.length; i++) {
list[i].print();
System.out.println(list[i] instanceof HP640); //현재 객체 확인
if(list[i] instanceof HP640) {
//list[i].call(); //부모는 자식멤버를 모름!!
//자기 자신의 고유기능이 필요한 경우에는
// 자신의 타입으로 형변환시켜 고유멤버를 사용한다.
// --> 다운캐스팅
HP640 hp = (HP640)list[i];
hp.call();
}
if(list[i] instanceof LG550) {
((LG550)list[i]).selfTest();
}
}
//추상클래스(인터페이스)와 참조형 형변화의 사용
// - 형제뻘 되는 클래스의 객체들을 일괄처리하기 위해서!
}//end m3();
}//end Ex97_Casting
//추상클래스(멤버구현 + 규칙선언)
abstract class Printer
{
public String model; //모델명
public abstract void print(); //프린터로써 가져야할 최소한의 행동규칙
}//end Printer
class HP640 extends Printer
{
public void print() {
System.out.println("HP640출력 : "+this.model);
}
public void call() {
System.out.println("자동으로 상담원 연결...");
}
}//end HP640
class LG550 extends Printer
{
public void print() {
System.out.println("LG550출력 : "+this.model);
}
public void selfTest() {
System.out.println("자가 진단 테스트...");
}
}//end LG550
제네릭, Generic - 내부구조나 알고리즘을 동일하게 구현하되, 취급되는 데이터의 자료형만 다른 메서드나 클래스를 구현하는 경우에 사용 - 즉, 일반화된 클래스나 메서드를 정의하는 기법 - 컴파일때 자료형이 결정됨. - 타입 변수를 사용
1. 제네릭 클래스 2. 제네릭 매서드 - 메서드 오버로딩과 구분할것!
Ex98~100_Generic 소스 참고
public class Ex98_Generic
{
public static void main(String[] args)
{
//Ex98_Generic.java
WrapperInt n1 = new WrapperInt(10);
n1.setData(20);
System.out.println(n1.getData());
WrapperDouble d1 = new WrapperDouble(3.15);
System.out.println(d1.getData());
WrapperString s1 = new WrapperString("홍길동");
System.out.println(s1.getData());
// 참조형은 산술연산 피연산자로서 사용 불가 : Down Casting 필요
WrapperObject o1 = new WrapperObject(20);
System.out.println(o1.getData());
System.out.println((int)o1.getData()+10);
o1.setData(3.15);
System.out.println((double)o1.getData()*2);
o1.setData("홍길동");
System.out.println(o1.getData()+"님");
System.out.println(o1.getData().toString() + "님");
System.out.println((String)o1.getData() + "님");
o1.setData(2500000000000L);
System.out.println(o1.getData());
GenericTest gt = new GenericTest();
gt.a = 10000;
System.out.println(gt.a+55555);
GenericTest gt2 = new GenericTest();
gt2.b = "테스트";
System.out.println(gt2.b);
Wrapper w1 = new Wrapper(100);
System.out.println(w1.getData() + 100);
Wrapper w2 = new Wrapper(1.23);
System.out.println(w1.getData() * 2);
Wrapper w3 = new Wrapper("호호호");
System.out.println(w1.getData()); //return String
}
}
//요구사항] int 타입을 다루는 래퍼클래스를 구현하시오
//요구사항] Double 타입을 다루는 래퍼클래스를 구현하시오
//요구사항] String 타입을 다루는 래퍼클래스를 구현하시오
class WrapperInt
{
private int data; //이 데이터를 다루기 위한 클래스
//생성자
public WrapperInt(int data) {
this.data = data;
}
public void setData(int data) {
this.data = data;
}
public int getData() {
return this.data;
}
}
class WrapperDouble
{
private double data; //이 데이터를 다루기 위한 클래스
//생성자
public WrapperDouble(double data) {
this.data = data;
}
public void setData(double data) {
this.data = data;
}
public double getData() {
return this.data;
}
}
class WrapperString
{
private String data; //이 데이터를 다루기 위한 클래스
//생성자
public WrapperString(String data) {
this.data = data;
}
public void setData(String data) {
this.data = data;
}
public String getData() {
return this.data;
}
}
//해결책
class WrapperObject
{
private Object data; //이 데이터를 다루기 위한 클래스
//생성자
public WrapperObject(Object data) {
this.data = data;
}
public void setData(Object data) {
this.data = data;
}
public Object getData() {
return this.data;
}
}
//해결책2 - Generics
class Wrapper // T : 타입변수, 자료형 자체를 담을 수 있는 변수
{
private T data;
public Wrapper(T data) { // 생성자 이름은 가 들어가지 않는다.
this.data = data;
}
public void setData(T data) {
this.data = data;
}
public T getData() {
return this.data;
}
}
//제네릭 클래스 - <타입인자 T>가 추가
class GenericTest
{
public T a;
public U b;
}
////////////////////////////////////////////////////////////////////////////////////
import java.util.*;
class Ex99_Generics
{
public static void main(String[] args)
{
//Ex99_Generics.java
Test t1 = new Test();
Test2 t2 = new Test2();
t2.a = 10;
t2.b = 10;
Test2 t3 = new Test2();
t3.a = "홍길동";
t3.b = true;
Test3 t4 = new Test3();
t4.a = 1.1f;
t4.b = 2.2f;
t4.c = 3.3f;
Test3 t5 = new Test3();
t5.a = new Random();
t5.b = new Random();
t5.c = new Random();
}//end main
}
//제네릭클래스
class Test
{
public T a; //클래스 호출시 넘겨주는 데이터형이 멤버의 데이터형을 결정
}
class Test2
{
public T a;
public U b;
}
class Test3
{
public T a;
public T b;
public T c;
}
////////////////////////////////////////////////////////////////////////////////////
class Ex100_Generic_Method
{
private static int n = 100;
public static void main(String[] args)
{
//Ex100_Generic_Method.java
//제네릭 클래스
// - 멤버변수의 타입을 컴파일때 결정
//제네릭 메서드
// - 매개변수의 타입을 컴파일때 결정
//요구사항] 두개의 정수를 Swap하는 메서드 구현
Ex100_Generic_Method ex = new Ex100_Generic_Method();
ex.test();
Ex100_Generic_Method.test2();
swap2(100,200);
swap2("홍길동","아무게");
//객체메서드 안에서는
// - 객체멤버와 정적멤버 모두 접근 가능
//정적메서드 안에서는
// - 정적멤버만 접근 가능 : this사용이 불가하기때문
check(10); //int a
check("문자열"); //String a
check(true); //boolean a
check2(10, "문자열");
}
//스왑
public static void swap(int a, int b) {
System.out.println("Swap 전 : a -> " + a + ", b -> " + b);
int temp;
temp = a;
a = b;
b = temp;
System.out.println("Swap 후 : a -> " + a + ", b -> " + b);
}
//스왑 제네릭 메서드
public static void swap2(T a, T b) {
System.out.println("Swap 전 : a -> " + a + ", b -> " + b);
T temp;
temp = a;
a = b;
b = temp;
System.out.println("Swap 후 : a -> " + a + ", b -> " + b);
}
public static void check(T a) {
System.out.println("데이터 : "+a);
}
public static void check2(T a, U b) {
System.out.println("T : "+a);
System.out.println("U : "+b);
}
public void test()
{
System.out.println("객체메서드");
}
public static void test2()
{
System.out.println("정적메서드");
}
}
컬렉션, Collection
- 데이터 집합(데이터를 넣을 수 있는 공간의 집합)
배열 VS 컬렉션 - 길이가 고정(불변) VS 길이가 가변 - 타입이 고정 VS 타입이 Object - 컬렉션은 배열에 비하여 종류가 다양하고 기능이 풍부
Ex101_ ArrayList 예제
import java.util.*;
class Ex101_ArrayList
{
public static void main(String[] args)
{
//Ex101_ArrayList.java
//ArrayList
// - 컬렉션의 한 종류
// - 배열과 거의 유사(배열 2.0)
int[] list1 = new int[5];
ArrayList list2 = new ArrayList();
//list2[0] = 100;
//list2.add(100); //데이터 추가
//System.out.println(list2.get(0));
for(int i=0; i<100; i++) {
list2.add(i * 10);
System.out.println((int)list2.get(i) + 10);
}
for( Object n : list2 ) {
System.out.println("n : "+n);
}
}
}