14일차 접근제한자,어노테이션,상속

쿠우·2022년 4월 11일
0

접근제한자

(1)접근 제한자(Access Modifier)

-클래스 및 클래스의 구성 멤버에 대한 접근을 제한하는 역할
1)다른 패키지에서 클래스를 사용하지 못하도록 (클래스 제한)
2)클래스로부터 객체를 생성하지 못하도록 (생성자 제한)
3)특정 필드와 메소드를 숨김 처리 (필드와 메소드 제한)

(2)클래스의 접근 제한

-public
다른 개발자가 사용할 수 있도록 라이브러리 클래스로 만들 때 유용

-default
1)클래스 선언할 때 public 생략한 경우
2)다른 패키지에서는 사용 불가

(3)생성자 접근 제한

생성자가 가지는 접근 제한에 따라 호출 여부 결정

(4)필드와 메소드의 접근 제한

클래스 내부, 패키지 내, 패키지 상호간에 사용할 지 고려해 선언

(5)클래스 선언할 때 필드는 일반적으로 private 접근 제한

-읽기 전용 필드가 있을 수 있음 (Getter의 필요성)
-외부에서 엉뚱한 값으로 변경할 수 없도록 (Setter의 필요성)

(6)Getter

-private 필드의 값을 리턴 하는 역할 - 필요할 경우 필드 값 가공
-getFieldName() 또는 isFieldName() 메소드
1)필드 타입이 boolean 일 경우 isFieldName()

(7)Setter

-외부에서 주어진 값을 필드 값으로 수정
1)필요할 경우 외부의 값을 유효성 검사
-setFieldName(타입 변수) 메소드
1)매개 변수 타입은 필드의 타입과 동일


데이터를 설명하는 데이터 = 메타데이터


어노테이션

(1)어노테이션(Annotation)?

-프로그램에게 추가적인 정보를 제공해주는 메타데이터(metadata)

-어노테이션 용도
1)컴파일러에게 코드 작성 문법 에러 체크하도록 정보 제공
2)소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동 생성하게 정보 제공
3)실행 시(런타임시) 특정 기능 실행하도록 정보 제공

(2)어노테이션 타입 정의와 적용

-어노테이션 타입 정의
1)소스 파일 생성: AnnotatoinName.java
2)소스 파일 내용 --> public @interface AnnotationName{}
-어노테이션 타입 적용 @override
@AnnotationName ---> ex public void toString(){...}

(3)기본 엘리먼트 value

-어노테이션 적용할 때 엘리먼트 이름 생략 가능
-두 개 이상의 속성을 기술할 때에는 value=값 형태로 기술

(4)어노테이션 적용 대상

-코드 상에서 어노테이션을 적용할 수 있는 대상
-java.lang.annotation.ElementType 열거 상수로 정의
(@Target 을 보아라!)

(5)어노테이션 유지 정책

-어노테이션 적용 코드가 유지되는 시점을 지정하는 것
-java.lang.annotation.RetentionPolicy 열거 상수로 정의
1) SOURCE 소스상에서만 정보유지, 바이트코드에는 남지 않는다.
2) CLASS 바이트코드까지 정보를 유지한다. 리플렉션이용해서 얻지는 못한다.
3) RUNTIME 바이트코드도 유지 리플렉션을 통해 정보도 얻을 수 있다.

-리플렉션(Reflection): 런타임에 클래스의 메타 정보를 얻는 기능
1)클래스가 가지고 있는 필드, 생성자, 메소드, 어노테이션의 정보를 얻을 수 있음
2)런타임 시 어노테이션 정보를 얻으려면 유지 정책을 RUNTIME으로 설정

--------------------------------------기본적인 어노테이션 생성--------------------------
package annotationex;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME) //에너테이션 정보를 언제까지 유지할지
@Target({ // <<에너테이션을 어디다가 지정해야하는지 제한해주는 에너테이션 
	ElementType.TYPE,
	ElementType.FIELD,
	ElementType.CONSTRUCTOR,
	ElementType.METHOD,
	ElementType.PARAMETER,
	ElementType.LOCAL_VARIABLE,
	ElementType.PACKAGE,
//	ElementType.TYPE_USE, //메소드와 패키지를 제외한 타입과 관련된 부분만 모두 넣을 수있게 해줌 
                          // 타입이 없는 패키지와 메소드는 안됌! 타입있는 메소드는 가능 
})
@MyAnnotation   //스스로 생성됌.
public @interface MyAnnotation {
//	String value() ;   			   // 이름이 value인  Default element
	String value() default "3"  ;   			  
	
	int age() default 23;
	String name() default "koo";   // <- 어노테이션 속성
} // end annotation

* Clazz 객체의 레퍼런스를 얻는 방법 3가지

(1) 타입명.class 속성이용:
ex) Class clazz = String.class;

(2) 참조타입변수명.getClass() 메소드 이용:
ex) String name="Yoseph";
Class clazz = name.getClass();

(3) Class.forName(FQCN) 메소드 이용:
ex) Class clazz = Class.forName("java.lang.String");


(6)런타임시 어노테이션 정보 사용하기

-클래스에 적용된 어노테이션 정보 얻기
클래스.class 의 어노테이션 정보를 얻는 메소드 이용

-필드, 생성자, 메소드에 적용된 어노테이션 정보 얻기
다음 메소드 이용해 java.lang.reflect 패키지의 Field, Constructor, Method 클래스의 배열 얻어냄

(7)런타임시 어노테이션 정보 사용법

-Field, Constructor, Method가 가진 다음 메소드 호출
(is 구글링ㅋ)
1) isAnnotationPresent( Class<? extends Anotation> annotationClass )
: 지정한 어노테이션이 적용되었는지 여부를 boolean타입으로 리턴합니다. Class에서 호출했을 때 상위 클래스에 적용된 경우도 true를 리턴합니다.

2)getAnnotation( Class annotationClass )
: 지정한 어노테이션이 적용되어 있으면 해당 어노테이션을 리턴하고 없을 시 null을 리턴합니다. 마찬가지로 상위 클래스에 적용되어도 같습니다.

3)getAnnotations()
: 적용된 모든 어노테이션을 Annotation[] 배열로 받습니다. 상위클래스도 포함합니다.

4)getDelaredAnnotations()
: 상위 클래스를 제외한 직접 적용된 어노테이션 배열을 리턴합니다.

-------------------------------------에너테이션 정보사용-----------------------------------------
package annotationex;

import java.lang.reflect.Method;

public class PrintAnnotationExample {

	//Java Reflection API를 이용한 어노테이션 처리 -->시작은 Clazz객체(바이트코드 들고 있어서)얻는데 시작 
	public static void main(String[] args) {
		
		//1. Service 클래스로부터 메소드 정보를 얻음 
		Method[] declaredMethods = Service.class.getDeclaredMethods();
		
		//2. Method 객체를 하나씩 처리
		for(Method method : declaredMethods) {
			
			// 3. PrintAnnotation이 적용되어있는지 확인 
			if(method.isAnnotationPresent(PrintAnnotation.class)) {
				// 3-1. PrintAnnotation 객체 얻기 
				PrintAnnotation printAnnotation = method.getAnnotation(PrintAnnotation.class);
				
				// 3-2. 메소드 이름 출력
				System.out.println("["+method.getName()+"]");
				
				//3-3. 구분선 출력
				for(int i=0; i<printAnnotation.number(); i++) {
					System.out.println(printAnnotation.value());
				}//for
				System.out.println();
				
				try {
					
					// 3-4 메도스 호출
					method.invoke(new Service());
				} catch (Exception e) {}
				System.out.println();
			} //if
		}//for
		
		
	}// main

}// end class
-------------------------------------에너테이션본문-----------------------------------------
package annotationex;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PrintAnnotation {
	String value() default "-";
	int number() default 15;
	
} // end annotation

상속

(1)객체 지향 프로그램

-자식(하위, 파생) 클래스가 부모(상위) 클래스의 멤버를 물려받는 것
-자식이 부모를 선택해 물려받음
-상속 대상: 부모의 필드와 메소드

(2)상속(Inheritance) 개념의 활용

-상속의 효과
1)부모 클래스 재사용해 자식 클래스 빨리 개발 가능
2)반복된 코드 중복 줄임
3)유지 보수 편리성 제공
4)객체 다형성 구현 가능 ★★★★★

-상속 대상 제한
1)부모 클래스의 private 접근 갖는 필드와 메소드 제외
2)부모 클래스가 다른 패키지에 있을 경우, default 접근 갖는 필드와 메소드도 제외

-상속 키워드 =extends 키워드
(1)자식 클래스가 상속할 부모 클래스를 지정하는 키워드
(2)자바는 단일 상속 - 부모 클래스 나열 불가


자식 객체 생성할 때는 부모 객체부터 생성 후 자식 객체 생성
부모 생성자 호출 완료 후 자식 생성자 호출 완료
(부모 없는 자식 없다고 함)


(3)부모 생성자 호출(super(…))

-부모 객체 생성할 때, 부모 생성자 선택해 호출
-super(매개값,…) =매개값과 동일한 타입, 개수, 순서 맞는 부모 생성자 호출
-부모 생성자 없다면 컴파일 오류 발생
-반드시 자식 생성자의 첫 줄에 위치
-부모 클래스에 기본(매개변수 없는) 생성자가 없다면 필수 작성

----------------------------부모생성자 클래스 호출------------------------------------
public class DmbCellPhone extends CellPhone {

	int channel;
	
	DmbCellPhone(String model, String color, int channel){
		super(); //만일, 부모클래스의 생성자가 매개변수가 있으면 
				 // 개발자 명시적으로 부모 생성자를 가장 첫 행에서 호출해줘야한다.
		
	    System.out.println("DmbCellPhone::constructor invoked.");
//	    System.out.println("- super"+ super);
		this.model =model; 
		this.color = color;
		this.channel = channel;
	}
}

(4)메소드 재정의(@Override)

-부모 클래스의 상속 메소드 수정해 자식 클래스에서 재정의하는 것
-메소드 재정의(오바라이딩) 조건
1)부모 클래스의 메소드와 동일한 시그니처 가져야
2)접근 제한을 더 강하게 오버라이딩 불가
3)새로운 예외(Exception) throws 불가
-재정의로 인해 부모 메소드는 숨겨지는 효과 발생
1)자식의 재정의된 메서드가 수행된다.
2)사용하고자 하면 super.메소드이름을 통해서 사용
-@Override 어노테이션
1)컴파일러에게 부모 클래스의 메소드 선언부와 동일한지 검사 지시
2)정확한 메소드 재정의 위해 붙여주면 OK

------------------------------------부모 메소드 재정의 및 사용 ----------------------
package inherit;


public class Computer extends Calculator {

    // 다형성 -2 : 상속으로 물려받은 메소드를 재정의하면 상속메소드 호출시, 무조건! 재정의된 메소드호출된다.	
	@Override
	double areaCircle(double r) {
		System.out.println("Calculator :: areaCircle() invoked.");
		
		return Math.PI * r * r ;
	}// areaCircle
	
	
}
---------------------------------------자식 클래스---------------------------
package inherit;

public class ComputerEx {

	//다형성 -2 확인
	public static void main(String[] args) {
		int r = 10; 
		
		Calculator calculator =new Calculator();
		System.out.println("원면적 : " + calculator.areaCircle(r));
		System.out.println();

//		 --- 
		
		

		Computer computer = new Computer();
		System.out.println("원면적 : " + computer.areaCircle(r));
		
	}//main

}// end class


---------------------------------------부모 클래스---------------------------

package inherit;

//POJO: Plain Old Java Object : 진부하고 늙은 자바 클래스
public class Calculator { // POJO : 상속관계가 없는 단순 자바 클래스 

	
	double areaCircle(double r) {
		System.out.println("Calculator :: areaCircle(r)");
		
		return 3.141592 * r * r ;
	}// areaCircle
	
	
}

(5)final 클래스와 final 메소드

-final 키워드의 용도
1)final 필드: 수정 불가 필드
2)final 클래스: 부모로 사용 불가한 클래스(자식생성불가/정관수술)
3)final 메소드: 자식이 재정의할 수 없는 메소드(그냥 고대로 써야함)

-------------------------부모 클래스 final 메소드 선언 -------------------------------------
package inherit.finalex;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Car {
	// 상태 필드 
	public int speed;
	
	//1. 메소드
	public void speedUp() {
		speed +=1;
	}// speedUp
	
	
	//2. final 메소드 - 자식클래스에서 메소드 재정의 불허 
	public final void stop() {
		System.out.println("Car :: stop() invoked");
		
		speed = 0; 
	}//stop
	
}
-------------------------자식 클래스 final 메소드 재정의 불가 -------------------------------------
package inherit.finalex;

public class SportsCar extends Car {

	
	
	@Override
	public void speedUp() {
		speed += 10;
	} //speedUp
	
	// final 메소드로 오버라이딩 불가 
//	public final void stop() {
//		System.out.println("스포츠카 멈추기");
//		speed = 0; 
//	}
	
	
	
}// end class
------------------------- final 클래스 생성-------------------------------------
package inherit.finalex;

public final class Member {
 ;;
} //class end
------------------------- final 클래스 사용 불가-------------------------------------
package inherit.finalex;

public class VeryVeryImportantPerson /* extends Member */ {

} //class end

(6)protected 접근 제한자

-상속과 관련된 접근 제한자
1)같은 패키지: default와 동일
2)다른 패키지: 자식 클래스만 접근 허용

---------------------------------------생성자 protected  부모 클래스 생성 ------------------
package inherit.pakege1;

public class A {
	protected String field;
	
	protected A() { // 의미를 오해 말아야한다. 즉 new 생성자가 아니다!!!!!
		;;
	}// default constructor
	
	protected void method( ) {}
	
	
}
----------------------------------- 같은 패키지에서 접근 ------------------------------------
package inherit.pakege1;

public class B {
	
	public void method() {
		A a = new A();
		
		a.field = "value"; 
		
		a.method();
	}// method
}//end class
----------------------------------- 다른 패키지에서 접근 ------------------------------------
package inherit.pakage2;

import inherit.pakege1.A;

public class C { // C는 A 의 default 접근제한으로 막힘 

	public void method() {
//		A a = new A(); 
//		
//		a.field = "value"; 
//		
//		a.method();
	}// method
}
----------------------------------- 다른 패키지에서 자손이 접근 ------------------------------------
package inherit.pakage2;

import inherit.pakege1.A;

public class D extends A{  // 자식이어서 protected 사용 가능

	public D() {
		super(); //   protected의 접근제어자를 가진 생성자는 생성자만 super()로만 참조 할 수 있게 해준다.
		
//		A a = new A(); << protected의 접근제어자를 가진 생성자는 객체생성을 허용하는게 아니다. 
		
		this.field = "value"; 
		
		this.method();
	}// method
}//end class
profile
일단 흐자

0개의 댓글

관련 채용 정보