Recent Posts
Recent Comments
Link
11-21 14:38
Today
Total
관리 메뉴

삶 가운데 남긴 기록 AACII.TISTORY.COM

자바 클래스와 메서드 본문

DEV&OPS/Java

자바 클래스와 메서드

ALEPH.GEM 2022. 3. 28. 10:42

 

객체지향 언어

객체지향 언어는 캡슐화, 상속, 다형성이 특징입니다.

 

클래스(class)

클래스는 기본 데이터 타입들(int , char, ...)로 된 변수(필드)들과 그들을 다루기 위한 동작(method)들을 정의한 객체(object)로 인스턴스(instance: 메모리에 구현된 객체)를 생성하기 위한 설계도입니다.

클래스 내부에 정의된 변수(필드)와 메서드들을  그 객체의 멤버(member)라고 부릅니다.

클래스 이름은 대문자로 시작하도록 이름을 정하는 것이 관례입니다.

 

캡슐화

데이터(필드)를 외부로부터 숨겨서(은닉화) 접근을 허용하지 않는 대신 제어 가능한 일부 필드와 메서드를 제공합니다.

자바에서는 접근 제한자를 이용하여 구현합니다.

 

접근 제한자

  • public : 모든 접근 허용
  • protected : 같은 패키지 객체와 상속 관계 객체들만 허용
  • default : 같은 패키지에 있는 객체만 허용(생략 가능)
  • private : 현재 객체에서만 허용

 

메서드 오버로딩(method overloading)

동일한 메소드 이름으로 전달인자의 자료형이나 개수를 다르게해서 다른 작업을 수행하게 할 수 있게 여러번 정의하는 것입니다.

단, 접근 지정자나 리턴 값을 달리하는 것은 오버로딩이 아닙니다.
그래서 반드시 전달 인자의 개수나 자료형으로만 구분해서 메소드를 각각 정의해야 합니다.

public class MethodTest01 {
 	//int형 전달인자 1개인 경우 절대값을 구해서 결과를 리턴하는 메소드
 	int abs(int num){             
  		if(num < 0){
			num = -num;
 		}
 	return num;
	}

//double형 메소드 오버로딩
double abs(double num){          
	if (num < 0){
		num = -num;
	}
 	return num;
}

//int와 double형 전달인자를 받아 절대값을 구해서 
//결과를 출력하는 메소드 오버로딩, 리턴값 없음
//리턴형이 다르지만 전달인자 개수와 형이 다르기 때문에 오버로딩.
void abs(int num0, double num1) {
	int absnum0 = 0;
	double absnum1 = 0;
	if (num0 < 0){
		absnum0 = -num0;             //음수인경우 부호 바꿈
	}else{
		absnum0 = num0;              //양수이면 그대로
	}
	if (num1 < 0){
		absnum1 = -num1;           
	}else{
		absnum1 = num1;
	}
	System.out.println(num0 + " 와 " + num1 + " 의 절대값은 " + absnum0 + " 그리고 " + absnum1 + " 입니다.");
}


public static void main(String[] args){
	MethodTest01 ab = new MethodTest01();   
	//MethodTest01 참조 자료형의 인스턴스 생성자를  호출하여 인스턴스 ab를 메모리에 할당
	int var1 = -10, var2;                         //int형 변수 선언과 값 할당
	double var3 = 3.14, var4;                     //double형 변수 선언과 값 할당
	var2 = ab.abs(var1);                           //인스턴스 ab의 맴버에 접근할 땐 . (점:dot) 을 이용
	System.out.println(var1 + "의 절대값은 " + var2);
	var4 = ab.abs(var3);
	System.out.println(var3 + "의 절대값은 " + var4);
	var1 = 29;                                //int형 변수에 새로운 값 할당             
	var3 = -2.14;                             //double형 변수에 새로운 값 할당
	ab.abs(var1, var3);
}


}

 

 

 

생성자(constructor)

생성자는 클래스 이름과 동일한 메서드로 인스턴스를 생성해줍니다.

자바는 기본(default) 생성자를 제공해서 인스턴스가 생성될 때 초기화 작업을 수행해 줍니다.

또한, 기본 생성자는 생략 가능합니다.

생성자 또한 메서드 이기 때문에 일반 메서드처럼 오버 로딩(overloading)을 이용하여 여러 가지로 수행할 동작을 정의할 수 있습니다.

class SetDate{
	private int year;
	private int month;
	private int day;
    
    //전달 매개 변수 3개로 생성자 정의
	public SetDate(int a, int b, int c){
		year = a;
		month = b;
		day = c;
	}
    public void print(){
		System.out.println(year+ "/" + month + "/" + day);
	}
};

public class ConstructorTest {
	public static void main(String[] args){
		SetDate d1 = new SetDate(2011, 4, 28);      //전달 매개 변수 3개로 생성자 호출
        /* 생성자 매개변수 갯 수 나 자료형을 잘못 적으면 에러*/
		d1.print();
	}
}

 

클래스의 상속

클래스의 필드 변수와 메서드들을 확장(상속)해서 새로운 멤버 변수와 기능을 추가할 때 extends를 이용해 클래스를 확장할 수 있습니다.

멤버 변수와 메서드를 물려주는 클래스를 슈퍼클래스(부모 클래스) super class 라 하고 물려받아 새로운 멤버 변수와 메서드를 추가하는 클래스를 서브클래스(자식 클래스) sub class라고 합니다. 
슈퍼클래스의 모든 멤버 변수와 메서드들을 서브클래스에서 물려받았기 때문에 서브클래스에서는 수퍼클래스의 모든 멤버 변수와 메서드를 사용할 수 있습니다.

하지만, 서브클래스는 새로운 멤버와 메서드가 추가되었기 때문에 수퍼클래스에서는 서브클래스의 멤버 변수와 메서드를 사용하지 못합니다.

서브클래스에는 슈퍼클래스에 없는 멤버와 메서드가 추가되었기 때문이죠.

또한, 자식 클래스는 부모클래스의 멤버를 모두 상속 받았으므로 부모 클래스의 생성자로도 인스턴스를 생성할 수 있습니다.

class Dimension2{
	private int x;
	private int y;
	public int getX(){
 		return x;
	}
	public void setX(int set_x){
		x = set_x;
	}
 	public int getY(){
		return y;
	}
	public void setY(int set_y){
		y = set_y;
	}
};

//기존 수퍼클래스로부터 멤버를 상속 받아 확장
class Dimension3 extends Dimension2{
	//새로 추가된 멤버변수	
	private int z;                 
	//새로 추가된 메소드
	public int getZ(){
		return z;
	}
	//새로 추가된 메소드    
	public void setZ(int set_z){
		z = set_z;
	}
};

class ExtendsTest{
	public static void main(String[] args){
		Dimension3 pt0 = new Dimension3();
		pt0.setX(1024);
		pt0.setY(768);
		pt0.setZ(640);
		System.out.println( "(x,y,z) 좌표: (" + pt0.getX() + "," + pt0.getY() + "," + pt0.getZ() + ")" );
	}
}

 

메서드 오버 라이딩(Method Overriding) 

수퍼 클래스에서 정의되었던 메서드를 서브 클래스에서 다시 정의해서 사용하는 것입니다.
수퍼 클래스에서 정의되었던 메서드는  서브 클래스에서 재정의 되었으므로 은닉되며 서브 클래스의 메서드가 사용됩니다. 

 

예약어 this

this는 선언하지 않고도 사용할 수 있는 객체(인스턴스) 자신을 참조하는 참조 자료형입니다.
멤버 변수(속성,필드)는 객체(인스턴스)가 생성될 때마다 다른 값을 가질 수 있습니다.
하지만 멤버 함수(메서드)는 모든 객체가 동작이 동일합니다.
그래서 메서드는 인스턴스들이 모두 같이 공유하기 때문에 this는 메서드가 호출되었을 때 어떤 인스턴스의 메서드인지 구분할 목적으로 사용합니다.
이러한 this를 사용해야만 하는 경우가 있습니다.
메서드의 전달 인자(argument)가 객체 멤버 변수와 이름이 동일한 경우 예를 들어

public void Setyear(int year){
	year = year;    // 멤버와 전달 매개 변수 이름이 같은 경우 둘 다 매개변수 인걸로 취급.
	this.year = year;    //왼쪽의 year변수가 멤버의 변수라는 것을 구분해 주기 위해서 this를 표시
}

메인 메서드 안에서는 객체 참조 변수가 멤버를 참조합니다.
하지만 객체의 메서드로 넘어가게 되면 객체의 메서드는 같은 클래스에 의해 생성된 객체들이 공유하기 때문에 컴파일러가 자동으로 this를 이용하여 멤버들을 참조합니다.

 

생성자 this()

같은 클래스 내에 다른 생성자를 호출할 때 사용합니다.

class SetDate{
	private int year, month, day;           //맴버변수 선언
	// 전달인자(매개변수) 없는 생성자 정의
    public SetDate(){
		this(2011, 4, 28);        //생성자 안에서 자기 자신의 다른 생성자(매개변수 3개 짜리)를 호출하고 있음
	}
    
 	// 매개변수 3개 짜리 생성자 정의   
	public SetDate(int year, int month, int day){
		this.year = year;             /* = 의 왼쪽에 있는 year 변수는 객체의 멤버이고 = 의 오른쪽에 있는 year 변수는 메소드를 호출 할 때 전달 받은 매개변수이다. */ 
		this.month = month;
		this.day = day;
	}
    
 	public void print(){
  		System.out.println(year + "/" + month + "/" + day);
	}
}

public class ConstructorThis{
	public static void main(String[] args){
		SetDate d1 = new SetDate();          //d1객체는 매개변수 없는 생성자 호출
		d1.print();
		SetDate d2 = new SetDate(1999, 9 , 9);         //d2객체는 매개변수 3개 짜리 생성자 호출
		d2.print();
	}
}

 

참조 변수 super

만약 서브클래스에서 오버라이딩되어서 슈퍼 클래스의 은닉된 메서드를 사용하려면 super.메서드() 형식으로 접근할 수 있습니다.
메서드와 마찬가지로 멤버 변수 또한 서브 클래스에서 재정의하면 슈퍼 클래스의  기존 멤버는 은닉되는데 이때에도 슈퍼 클래스의 은닉 변수에 접근하려면 super.멤버변수  형식으로 접근할 수 있습니다.

class Dimension2{
	protected int x = 0;
	protected int y = 0;
	protected void viewPoint(){
		System.out.println( "(" + x + ", " + y + ")"); 
	}
};

class Dimension3 extends Dimension2{
	protected int z = 640;
	protected int x = 1024;            /*수퍼클래스의 멤버변수 x를 서브 클래스 에서 재정의*/ 
	protected int y = 768;             /*수퍼클래스의 멤버변수 y를 서브 클래스 에서 재정의*/ 
	protected void viewPoint()     //메소드 오버라이딩 {
	System.out.println("(" + x + ", " + y + ", " + z + ")");
	}
	protected void view2DPoint(){
		super.x = 1024;       //super 를 이용하여 수퍼클래스의 멤버 변수에 접근  
        super.y = 768;
		super.viewPoint();      //super를 이용하여 수퍼클래스의 메소드 사용 
	}
};

class SuperTest{
	public static void main(String[] args){
		Dimension2 point0 = new Dimension2();    //point0 은 2차원 좌표  
		Dimension3 point1 = new Dimension3();    //point1 은 3차원 좌표  
		point0.viewPoint();    //수퍼클래스의 원래 메소드  
		point1.viewPoint();    /*서브클래스의 재정의된 멤버변수를 출력하는 오버라이딩된 메소드*/  
		point1.view2DPoint();    /*키워드 super를 이용하여 은닉된 수퍼 클래스의 멤버를 바꾼 후 은닉된 수퍼클래스의 메소드로 출력 */ }
}

 

상속된 클래스에서의 생성자

class Dimension2{
    protected int x = 0;
    protected int y = 0;
    protected void viewPoint(){
        System.out.println( "(" + x + ", " + y + ")"); 
    }
};

class Dimension3 extends Dimension2{
    protected int z = 640;
    protected int x = 1024;     /*수퍼클래스의 멤버변수 x를 서브 클래스 에서 재정의*/ 
    protected int y = 768;      /*수퍼클래스의 멤버변수 y를 서브 클래스 에서 재정의*/ 
    //메소드 오버라이딩
    protected void viewPoint(){
        System.out.println("(" + x + ", " + y + ", " + z + ")");
    }
    protected void view2DPoint(){
        super.x = 1024;   //super 를 이용하여 수퍼클래스의 멤버 변수에 접근  
        super.y = 768;
        super.viewPoint();      //super를 이용하여 수퍼클래스의 메소드 사용 
    }
};

class SuperTest{
    public static void main(String[] args){
        Dimension2 point0 = new Dimension2();    //point0 은 2차원 좌표  
        Dimension3 point1 = new Dimension3();    //point1 은 3차원 좌표  
        point0.viewPoint();    //수퍼클래스의 원래 메소드  
        point1.viewPoint();    /*서브클래스의 재정의된 멤버변수를 출력하는 오버라이딩된 메소드*/  
        point1.view2DPoint();  /*키워드 super를 이용하여 은닉된 수퍼 클래스의 멤버를 바꾼 후 은닉된 수퍼클래스의 메소드로 출력 */ 
    }
}

 

업 캐스팅과 다운 캐스팅

참조 변수들 간의 형 변환(Type Casting)은 상속 관계에 있을 때만 가능합니다.

업 캐스팅

업 캐스팅은 슈퍼 클래스의 참조 변수가 서브 클래스의 인스턴스를 가리키는 것입니다.
컴파일러에 의해 암시적으로 형 변환됩니다.
업 캐스팅 후에는 부모로부터 상속받은 변수와 메서드만 사용할 수 있습니다.

다운 캐스팅

다운 캐스팅은 슈퍼 클래스의 참조 변수를 서브 클래스로 형 변환하는 것입니다.  
다운 캐스팅은 암시적으로(자동) 형 변환이 되지 않습니다.
다운 캐스팅은 명시적으로 형 변환해야 합니다.
캐스팅 후에도 실행 시 예외가 발생할 수 있으므로 업 캐스팅을 먼저 해준 참조 변수를 다시 다운 캐스팅을 해야 안전합니다.

class Parent{
    public void parentPrint(){
        System.out.println("수퍼 클래스 출력 메소드");
    }
};

class Child extends Parent{
    public void childPrint(){
        System.out.println("서브 클래스 출력 메소드");
    }
};

class DownCastingTest {
    public static void main(String[] args){
        Parent p1 = new Parent();
        Child c1;
        //c1 = (Child) p1;           /* 명시적 다운 캐스팅 실행시 예외 발생한다.*/
        //c1.parentPrint();
        //c1.childPrint();
        Parent p2 = new Child();  // 암시적 업캐스팅
        p2.parentPrint();
        //p.childPrint();   /* 컴파일 에러: 업캐스팅이 되면 서브 클래스의 메소드를 접근할 수 없다. */  
        Child c2;
        c2 = (Child) p2;   // 명시적 다운 캐스팅  
        c2.parentPrint();
        c2.childPrint();
    }
}

 

instanceof

instanceof 연산자는 해당 참조 변수의 타입을 검사해서 참과 거짓을 리턴해주는 연산자로 업 캐스팅되었을 때도 참을 리턴합니다.
사용 예)
참조변수 instanceof 타입  

서브 클래스에서 재정의한 오버라이딩의 경우 업 캐스팅을 하더라도 서브 클래스에서 오버라이딩된 메서드가 동작하게 됩니다.

class Parent{
    public void  parentPrint(){
        System.out.println("수퍼 클래스: ParentPrint 메소드");
    }
};

class Child extends Parent{
    public void parentPrint(){
        System.out.println("서브 클래스: 오버라이딩 된 ParentPrint 메소드");
    }
    public void childPrint(){
        System.out.println("서브 클래스: childPrint 메소드");
    }
};

class RefTest01{
    public static void main(String[] args){
        Child c = new Child();
        c.parentPrint();       //오버라이딩한 메소드 호출
        c.childPrint();
        Parent p;
        p = c;     
        p.parentPrint();
        /* 비록 참조 변수는 수퍼 클래스 형으로 참조 하지만 오버라이딩의 경우  업캐스팅 후에도 parentPrint() 메소드는 은닉되어 서브 클래스에서 오버라이딩 된 메소드가 호출된다. */
    }
}

 

정적(static) 변수

일반 멤버 변수가 생성자로 생성된 인스턴스에서 사용하지만 static 변수는 클래스에서 사용합니다.

클래스의 멤버들이 static으로 선언이 되면 메모리상에 단 한 개만 생성이 됩니다.

그래서 static 변수는 인스턴스가 생성되기 전에 메모리에 할당되기 때문에 생성자를 호출하기 전에도 사용이 가능합니다.
static 변수는 인스턴스들이 공유해서 사용하는 전역 변수 역할을 합니다.
그래서 인스턴스가 소멸해도 프로그램이 끝날 때까지 값을 유지합니다.
그리고 또한 인스턴스명으로도, 클래스명으로도 접근이 가능합니다.

 

정적(static) 메소드의 특징

static 변수가 private로 선언되어 있다면 그 변수를 다른 클래스로부터 접근을 할 수 없기 때문에 private static 변수를 제어하기 위한 static 메소드를 정의해야 합니다.

1. static 메소드는 this 를 사용할 수 없습니다.

왜냐하면 this는 인스턴스가 생성 되었을 때 해당 인스턴스를 기리키는 참조 변수인데 static은 모든 인스턴스에서 공유하기 때문에 각 인스턴스별로 구분할 수 없기 때문입니다.

2. static 메소드는 인스턴스 변수를 사용할 수 없습니다.

왜냐하면 인스턴스 변수는 인스턴스 단위에서만 사용하는 지역 변수 역할을 하기 때문입니다.

3. static 메소드는 오버라이딩(하위 클래스에서 재정의 하는 것)이 되지 않습니다.
수학 공식의 경우 계산 과정이 공식에 의해 규칙적이어서 매번 인스턴스를 생성해서 계산하는 것이 번거롭습니다. 그래서 바로 클래스로 접근해서 속성과 메소드를 사용하는 것이 효율적입니다. 그래서 자바에서 제공되는 Math 클래스에서는 거의 static 으로 선언이 되어 있습니다.
class StaticExample{
	private static int a = 1;      //정적변수 a는 클래스 단위 변수  
	private int b = 2;   //b는 인스턴스 변수 
	public static int c = 3;     //정적변수지만 다른 클래스에서 접근하기 위해 public으로 선언 
	//static 변수 a를 출력하기 위한 static 메소드
	public static void viewA(){
		System.out.println(a);
		/*System.out.println(b); */ 
		/*정적 메소드에서는 인스턴스 변수를 사용 못하기 때문에 주석을 제거하면 컴파일 에러*/ 
 	}
 
	//static 변수 a를 10으로 변경하기 위한 static 메소드
	public static void changeA(){
		a = 10;
	}
    
	//인스턴스 변수 b를 출력하는 인스턴스 메소드
	public void viewB(){
		System.out.println(b);
	}

	//인스턴스 변수 b를 20으로 변경하는 인스턴스 메소드
	public void chageB(){
		b = 20;
	}
}

public class StaticTest{
	public static void main(String[] args){
	StaticExample.viewA();
	/*생성자를 호출하기 전 클래스 명으로 정적 메소드로 정적 변수 접근해서 a의 초기값 1 출력*/
	StaticExample s0 = new StaticExample();               
	/*객체 참조변수 s0 으로 생성된 인스턴스를 가리킴*/  
	s0.viewB();            
	/*인스턴스 변수인 디폴트 생성자에 의해 b는 2로 초기화 되었으므로 2가 출력*/             
	/* s0.a = 11; */
	/*private static은 인스턴스에서 직접 접근 못하고 static 메소드로 접근해야함*/  
	s0.changeA();        
	/* 인스턴스 s0 에서 정적 메소드를 이용해 정적변수 a 값 변경*/  
	s0.viewA();           
	/*인스턴스 s0 에서 접근해서 바뀐 a값 10 출력*/  
	/* StaticExample.a = 20; */ 
	/*클래스 이름으로 접근하더라도 여기는 다른 클래스인 StaticTest 클래스 영역 이기 때문에 private 변수로 직접 접근은 불가*/  
	StaticExample.c = 30;	/* public으로 선언된 정적변수 c는 외부 클래스에서 직접 접근해 값 교체가 가능하다 */   
	System.out.println(StaticExample.c);	/* 정적 메소드를 통하지 않고서도 public 으로 선언된 c는 외부 클래스에서 static변수인 c로 접근이 가능 하기 때문에 30 출력*/  
	StaticExample s1 = new StaticExample();         /* 새로운 객체 s1 생성*/  
	s1.viewA();	/* 새로운 인스턴스 s1에서도 a값은 공유 되어  교체되었던 10이 출력 됨*/  
	/* s1.b = 20; */	/*s1의 인스턴스 변수인 b는 private로 선언 되어있기 대문에 외부 클래스에서 접근 못함*/  
	s1.chageB();	/* 인스턴스 메소드를 통해 s1의 b의 값을 변경 */  
	s1.viewB();		/* 변경된 s1의 b의 값 20 출력 */  
	s0.viewB();		/*s1 에서 b를 교체했어도 s1과 s0는 다른 인스턴스이기 때문에 공유되지 않고 s0의 b의 값은 2가 그대로 출력*/ 
	}
}

 

 

메서드 매개 변수 전달 방식

class Convert {
	//메소드 이름은 첫 글자를 소문자로 하는 것이 관습
	void convertSign(int a){                                
		a = -a;           
        /* 매개변수의 값을 Call by value 방식으로 받아 부호를 바꾸는 메소드 
        그러나  이 때의 a는 main메소드의 a를 가리키는 것이 아니라 변수 이름만 같은
        convertSign 메소드의 지역변수 이기 때문에 메인 메소드의 a에는 아무 영향이 없다. */
	}
};

class CallByValueTest {
	public static void main(String args){
		Convert c0 = new Convert();  
        /* Convert클래스의 생성자를 호출해서 생성된 인스턴스를 객체 참조 변수 c0에 할당 */
		int a = 123;                
        /*여기의 a는 메인 메소드의 지역변수 a 이지 
        Covert 클래스의 메소드에서 사용 된 a 와는 이름만 같지 별개의 변수이다. */
		System.out.println("convertSign 메소드 호출 전의 a값 출력: " + a);
		c0.convertSign(a);        //메소드의 매개변수를 x로 전달 Call by value 방식이다.
		System.out.println("convertSign 메소드 호출 후의 a값 출력: " + a);
	}
}

이렇게 메소드가 매개 변수로 값을 전달 받지만 원래 변수 값에는 영향이 없습니다.
이러한 매개 변수 전달 방식을 Call by value 방식이라고 합니다.

 

class RefExample {
	int a = 2103;   
};

class CallByRef {
	/* RefExample 형의 매개변수(참조자료형)로 값을 전달 받음 */
	void convertSign(RefExample x) {
		x.a = -(x.a);               //맴버변수 a의 부호를 교체
	}
};

class CallByRefTest {
	public static void main(String args){
		CallByRef cbr = new CallByRef();      
		RefExample re = new RefExample();
		System.out.println("메소드 호출 전 re.a 값: " + re.a);
		cbr.convertSign(re);            //매개변수 전달을 객체 참조 변수인 re로 전달한다.
		System.out.println("changeExample 메소드 호출 후 re.a 값: " + re.a);
	}
}

이 처럼 참조 변수에 의해 매개 변수가 전달 되면 해당하는 변수의 값을 변경 시킬 수 있습니다.
이러한 매개 변수 전달 방식을 Call by reference 라고 합니다.

 

다형성

다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미합니다.

자바에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있습니다.

 

singleton

프로그램 전체에서 하나의 인스턴스만 만들도록 강제해야 하는 경우가 있습니다.

그럴땐 외부에서 new 생성자()를 호출하지 못하도록 막아야 합니다.

그럴때 생성자의 접근제한자를 private로 지정해 줍니다.

그리고 static 필드를 하나 선언하고 자신의 인스턴스를 생성 후에 static 메서드로 getInstance() 메서드를 제공해줘야 합니다.

public class Singleton {
	private static Singleton single = new Singleton();	
	private Singleton() {}
	static Singleton getInstance() {
		return single;
	}
}

외부에서 위 클래스의 인스턴스를 얻기 위해서는 Singleton.getInstance() 으로 얻을 수 밖에 없고 아무리 여러번 호출하더라도 이들은 같은 인스턴스를 참조하게 됩니다.

즉, 인스턴스는 한개만 생성이 되게 됩니다.

 

final

필드 앞에 final 키워드를 붙이면 프로그램이 실행되는 동안 값이 변하지 않는 읽기전용입니다.

final이 붙은 클래스는 상속할 수없습니다. 

final이 붙은 변수는 생성자나 선언하는 곳에서만 초기화 할 수있습니다. 

final이 붙은 메서드는 오버라이딩을 할 수 없습니다.

원주율 값이나 상수인 경우 static final 로 설정합니다.

 

getter()/setter()

객체의 필드(변수)들을 외부에서 변경하면 값의 무결성을 보장할 수 없습니다.

그래서 보통 변수의 외부 접근을 막고 대신 getter()와 setter()메서드를 제공해서 외부에서 변수를 읽기/쓰기를 할 때 getter()와 setter()를 통해서만 접근하도록 설계합니다.

 

Annotation

컴파일러에게 문법 에러를 체크하도록 정보를 제공하거나 실행시 특정 기능을 실행하도록 정보를 제공하는 것을 어노테이션이라고 합니다.

또, 어노테이션을 이용해 개발 툴이나 빌드 툴들이 코드를 자동 생성하도록 정보(힌트)를 제공합니다.

이 어노테이션은 실제 사용법은 추후 실제 코딩을 하면서 알아봅시다.

 

 

 

 

 

728x90

'DEV&OPS > Java' 카테고리의 다른 글

중첩 클래스 중첩 인터페이스  (0) 2022.04.05
추상 클래스와 인터페이스  (0) 2022.03.31
조건문과 제어문  (0) 2022.03.25
자바 연산자  (0) 2022.03.24
자바 자료형과 변수  (0) 2022.03.22