본문 바로가기
JAVA

[JAVA]Object, 제네릭 클래스, 추상 메써드

by KhyeonS 2022. 7. 28.

Object, 제네릭 클래스, 추상 메써드 에 대해서 알아보자


Object

Object는 최상위 클래스 객체이다.

현재 클래스에서 설정한 메써드가 어떤 때는 String으로 받고 어떤 때에는 int 로 받는다면 원래는 Method Overloading으로 처리할 수 있지만, Object를 사용할 수도 있다.

원래 C에서 구조체(construct)와 유사한 개념으로 매개변수에 따라서 자유롭게 받을 수 있게한다.gkwlaks alfl tjsdjsgownf vlfdysms djqtek.

int[] a= {10, 20, "철수", 'A'}는 불가하지만

Object[] a={10, 20, "철수", 'A'}식으로 object 객체는 가능하다.

 

package java09;
class ExtendsEx1{              // ExtendsEx1 클래스 : Object 멤버 변수(객체)
	Object value;
public Object getValue() {
	return value;
}
public void setValue(Object value) {
	this.value =value;
	System.out.println(value);
}
}
public class Test01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExtendsEx1 v1 = new ExtendsEx1();
		v1.setValue("test");  // 같은 ExtendsEx1클래스에서 객체를 생성했는데 문자열 입력
		ExtendsEx1 v2 = new ExtendsEx1();
		v2.setValue(100); 	// 같은 ExtendsEx1클래스에서 객체를 생성했는데 정수 입력
		ExtendsEx1 v3 = new ExtendsEx1();
		v3.setValue('F');   // 같은 ExtendsEx1클래스에서 객체를 생성했는데 문자 입력
		// int 1 = (Int)v2.getValue()식으로 Object를 강제 Integer로 형변환
		//이 필요했지만 기본자료형으로 자동 형변환이 된다
		
		System.out.println("--------------");
		int i =(int)v2.getValue();
		System.out.println(i+1);
		
	}

}

위에 예제를 오버로딩으로 처리하기

package java09;

class ExtendEx1{
	String value1;
	int value2;
	char value3;
	public Object getValue() {
		return value1;
		
}
	public void setValue(String value1) {
		this.value1 = value1;
		System.out.println(value1);
		
	}
	public void setValue(int value2) {
		this.value2 = value2;
		System.out.println(value2);
		
	}
	public void setValue(char value3) {
		this.value3 = value3;
		System.out.println(value3);
		
	}
}

public class Test02 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExtendEx1 v1 =  new ExtendEx1();
		v1.setValue("test");
		ExtendEx1 v2 = new ExtendEx1();
		v2.setValue('A');
		ExtendEx1 v3 = new ExtendEx1();
		v3.setValue(100);
	}

}

***제네릭 클래스

제네릭 프로그래밍이란 일반적인 코드를 작성하고 이 코드를 다양한 타입의 객체레 대하여 재사용하는 객체지향(OOP)기법이다. 원하는 타입의 객체만 받아들이기 위한 방법으로 볼 수 있다. 결국 하나의 메소드에서 여러가지 타입을 한 번에 다 지원 하는 클래스가 제네릭 클래스라 할 수 있다.

 

예를 들어 클래스를 하나 만들고, 내부 메서드에서 int 만 아니라 원하는 자료형(객체) 타입 String이나 char등을 다양하세 지원하고 싶을때 사용한다고 볼 수 있다. 제네릭 타입은 기본 자료형을 인식하지 않으므로 int,double등의 기본 자료형을 제네릭 타입으로 이용하고자 할때는 <Integer>, <Double>등의 클래스를 이용해야 한다. 그리고 제네릭 타입은 반드시 

 

package java09;
class GenEx<T> { //T stands for Type
   T value;  //전체를 하나의 변수로 취급, 원래는 value가 변수이다.
   public T getValue() {
	   return value;
   }
   public void setValue(T value) { // value가 매개변수인데 Type에 맞춰서 들어감
	   this.value = value;
   }
}

public class Test03 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		GenEx<String> v1 = new GenEx<String>(); //객체를 생성할 때  Type을 정해줌, 반드시 문자열만 들어와야함
		v1.setValue("100");
		v1.setValue("200");
		System.out.println(v1.getValue());
		GenEx<Integer> v2 = new GenEx<Integer>();
		v2.setValue(1000);
		System.out.println(v2.getValue() + 10);
		GenEx<Double> v4 = new GenEx<Double>();
		v4.setValue(3.14);
		System.out.println(v4.getValue());
		
	}

}

package java09;

class Gen <T>{  // 제네릭 타입인 것을 Class_명이나 Method_명 두 곳중 한 곳에 써주면 되는 데
	//메써드를 제네릭 타입으로 한다면 Mathod_명에 T를 붙이는 것이 좋다.
	public <T> void printArr(T arr[]) { //이제부터는 배열에 들어가는 데이터 타입이 엄격!!
		// printArr(T[] arr)도 가능, 앞에서 T value한 것이나 여기서 (T arr[])한 것이 동일
		for (int i=0; i<arr.length; i++) {
			System.out.print("  "+arr[i]);
		}
		System.out.println();
		System.out.println("--------------");
	}
}


public class Test04 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		Integer[] iArr= {1, 2, 3, 4, 5}; //iArr, dArr, cArr는 일종의 배열 변수_명
		Double[] dArr = {1.1, 2.2, 3.3, 4.4, 5.5};
		Character[] cArr = {'A', 'B', 'C', 'D', 'E'};
		String[] sArr = {"I", "like", "Java", "so", "much"}; 
		Gen gen = new Gen(); //제네릭 타입은 반드시 객체로 처리 
		gen.printArr(iArr); 
		gen.printArr(dArr); //printArr() 메써드를 호출해서 사용
		gen.printArr(cArr);
		gen.printArr(sArr);
		
	}

}

 


추상 메써드와 추상 클래스

-추상 메서드의 구성: [접근제한] abstract [반환형] [메서드 명]();

//{} 없이 ; 으로 마무리됨

abstract[접근제한] [반환형] [메서드명]();

//{}없이 ; 으로 마무리됨

메써드에서 수행할 작업을 완성시키지 않은 미완성으로 두고, 나중에 자식 클래스에서 이 부모의 추상메써드를 호출해서 재정의 (Method Overriding)하여 사용하게 만드는 것으로 전체 프로그래밍에서 일관성을 줄 수 있다. 따라서 추상메서드는 수행할 작업을 구현해주는 몸체가 없고 abstact로 시작한다.

 

추상메써드는 몸체가 없기 때문에 이를 "미완성적 개념"이라 한다. 그러므로 이 미완성적 메써드를 자식이 상속받아서 완성 시켜야한다는 것이 조건이다. 재지정해서 사용하지 않아도 무조건 자식은 상속받아서 객체로 가지고 있어야 한다!!!

 

-추상 클래스의 구성 [접근제한] abstract class[클래스 명]{

                                  ..... }구문이다.

추상메써드가 한 개이상 정의 되어 있는 클래스를 추상 클래스라고 하는데, 추상 클래스또한 abstract 를 붙여서 자신이 추상 클래스임을 명시 해줘야 한다.

package java09;
abstract class AbsEx{
	int value = 100;
	final int VALUE2 = 1000; //상수는 앞에 final을 붙이고 보통 변수_명을 대문자로 한다.
	public int getValue() {
		return value;
	}
	abstract public void setValue(int n); //추상 메써드, {}속에 하는일이 없다!!!!
}
class AbsChild extends AbsEx{
	int age = 10;
	@Override
	public void setValue(int n) { // 부모 추상클래스의 메써드를 호출해서 새지정
		age += n; //age = age + n 추상 메써드가 할 일을 기술
		
	}
	@Override
	public int getValue() {
		return age;
	}
}
public class Test05 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		AbsEx a1 = new AbsEx(); 
		//추상 클래스를 호출해서 작업하려면 추상클래스를 객체로 만들지 못하고 추상메써드가
		//사용되게 설정한 자식 클래스로 객체를 만들어야 한다.
		AbsChild a2 = new AbsChild();
		a2.setValue(20);
		System.out.println(a2.getValue());
			
		
	}

}

 

package java09;


abstract class AbsClass{    //아래 추상 메써드를 가지고 있으므로 추상 클래스
	int value = 100;
	public int getValue() {
		return value;
	}
	public abstract int changeValue(); // 하는 일이 없으므로 추상 메써드
}
class AbsChild1 extends AbsClass{
	public int changeValue() {  // 추상 메써드를 상속받아서 구현 
		return value += 10;
	}
}
class AbsChild2 extends AbsClass{   // 추상 메써드를 상속받아서 구현 
	public int changeValue() {
		return value -=3;
	}
}

public class Test06 {

	public static void main(String[] args) {
//		AbsClass a1 = new AbsClass(); // 부모 추상 클래스에서 객체 생성 못함!!!
		AbsChild1 a1 = new AbsChild1();
		System.out.println(a1.changeValue()); // 110
		AbsChild2 a2 = new AbsChild2();
		System.out.println(a2.changeValue()); // 97
		System.out.println("---------------");
		
//		System.out.println(a1.getValue()); // 110
//		System.out.println(a2.getValue()); // 97
		Test06 ts = new Test06();
		ts.test(a1);
	    ts.test(a2);
		System.out.println("---------------");	
	}
	
	public void test(AbsClass n) { 
		//메써드릐 인자로 부모 클래스를 메써드의 인자로 사용했기 때문에 
		//모든 부모와 상속받은 자식 클래스들의 멤버들이 딸려서 사용될 수 있다.
		System.out.println(n.changeValue());
	}

}

 

'JAVA' 카테고리의 다른 글

[JAVA] 예외 처리  (0) 2022.08.01
[JAVA]인터페이스, 열거형, 내부클래스  (0) 2022.07.29
[JAVA] 상속  (0) 2022.07.27
[JAVA] Overload/ Overriding  (0) 2022.07.26
[JAVA] 가변 인수  (0) 2022.07.26

댓글