1.  final 필드와 상수

✏️  값을 변경하는 것을 막고 읽기만 허용할 때 사용

 

1)  final 필드 선언

final 타입 필드 [ =초기값];

 

  ⚒️  final 필드는 초기값이 저장되면 이것이 최종적인 값이 되어 실행 도중 값을 수정 X

  ⚒️  final 필드에 초기값을 줄 수 있는 방법은 2가지

  • 필드 선언 시에 초기값 대입
  • 생성자에서 초기값 대입

  ⚒️ 고정된 값이라면 필드 선언 시에 주는 것이 간단하지만 복잡한 초기화 코드가 필요하거나 객체 생성 시에 외부에서 전달된 값으로 초기화한다면 생성자에서 해야 한다.

        ⚡️  초기값을 주지 않고 final 필드를 그대로 남겨두면 컴파일 에러가 생김

public class Korean {
	//인스턴스 final 필드 선언
	final String nation = "대한민국";
	final String ssn;
	
	//인스턴스 필드 선언
	String name;

	//생성자 선언
	public Korean(String ssn, String name) {
		this.ssn = ssn;
		this.name = name;
	}
}
public class KoreanExample {
	public static void main(String[] args) {
		//객체 생성 시 주민등록번호와 이름 전달
		Korean k1 = new Korean("123456-1234567", "감자바");
		
		//필드값 읽기
		System.out.println(k1.nation);
		System.out.println(k1.ssn);
		System.out.println(k1.name);

		//Final 필드는 값을 변경할 수 없음
		//k1.nation = "USA";
		//k1.ssn = "123-12-1234";

		//비 final 필드는 값 변경 가능
		k1.name = "김자바";
	}
}

 


2)  상수 선언

static final 타입 상수 [ =초기값];

 

  ⚒️  불변의 값을 저장하는 필드를 자바에서는 상수 constant 라고 부름

         ex. 원주율 파이나 지구의 무게 및 둘레 등

  ⚒️  상수는 객체마다 저장할 필요가 없고, 여러 개의 값을 가져도 안되기 때문에 static이면서 final인 특성을 가져야 함.

  ⚒️  상수 이름은 모두 대문자로 작성하는 것이 관례. 서로 다른 단어가 혼합된 이름이라면 언더바(_)로 단어들을 연결함

static final double PI = 3.14159;
static final double EARTH_SURFACE_AREA = 5.147185403641517E8;

 

  ⚒️  상수는 정적 필드 이므로 클래스로 접근

클래스명.상수

 

public class Earth {
	//상수 선언 및 초기화
	static final double EARTH_RADIUS = 6400;

	//상수 선언
	static final double EARTH_SURFACE_AREA;
	
	//정적 블록에서 상수 초기화
	static {
		EARTH_SURFACE_AREA = 4 * Math.PI * EARTH_RADIUS * EARTH_RADIUS;
	}
}
public class EarthExample {
	public static void main(String[] args) {
		//상수 읽기
		System.out.println("지구의 반지름: " + Earth.EARTH_RADIUS + "km");
		System.out.println("지구의 표면적: " + Earth.EARTH_SURFACE_AREA + "km^2");
	}
}

 

 


2.  접근 제한자  Access Modifier

 

🚀  중요한 필드와 메소드가 외부로 노출되지 않도록 해 객체의 무결성(결점이 없는 성질)을 유지

🚀  default는 접근 제한자가 아니라 접근 제한자가 붙지 않은 상태!

접근 제한자 제한 대상 제한 범위
public 클래스, 필드, 생성자, 메소드 없음
protected 필드, 생성자, 메소드 같은 패키지이거나, 자식 객체에만 사용 가능
(default) 클래스, 필드, 생성자, 메소드 같은 패키지
private 필드, 생성자, 메소드 객체 내부

 

 

1)  클래스의 접근 제한

  ⚒️  클래스는 public과 default 접근 제한을 가질 수 있다.

[ public ] class 클래스 { ... }
  • 클래스 선언할 때 public 접근 제한자를 생략했다면 클래스는 default 접근 제한을 가진다.
  • 이 경우 클래스는 같은 패키지에서는 아무런 제한 없이 사용할 수 있지만 다른 패키지에서는 사용할 수 없게 된다.
  • public을 붙였다면 다른 패키지에서도 사용 가능

 

 


2)  생성자의 접근 제한

  ⚒️  생성자는 public, default, private 접근 제한을 가질 수 있다.

public class ClassName {
    // 생성자 선언
    [ public | private ] ClassName(...) {...}
}

 

접근 제한자 생성자 설명
public 클래스(...) 모든 패키지에서 생성자를 호출할 수 있다.
= 모든 패키지에서 객체를 생성할 수 있다.
default 클래스(...) 같은 패키지에서만 생성자를 호출할 수 있다.
= 같은 패키지에서만 객체를 생성할 수 있다.
private 클래스(...) 클래스 내부에서만 생성자를 호출할 수 있다.
= 클래스 내부에서만 객체를 생성할 수 있다.

 

package ch06.sec13.exam02.package1;

public class A {
	//필드 선언
	A a1 = new A(true);
	A a2 = new A(1);
	A a3 = new A("문자열");

	//public 접근 제한 생성자 선언
	public A(boolean b) {
	}
	
	//default 접근 제한 생성자 선언
	A(int b) {
	}

	//private 접근 제한 생성자 선언
	private A(String s) {
	}
}
package ch06.sec13.exam02.package1;

public class B {
	// 필드 선언
	A a1 = new A(true); 	//o
	A a2 = new A(1); 	    //o
	//A a3 = new A("문자열");	//x
}

 


3)  필드와 메소드의 접근 제한

  ⚒️  필드와 메소드는 public, default, private 접근 제한을 가질 수 있다.

// 필드 선언
[ public | private ] 타입 필드;

// 메소드 선언
[ public | private ] 리턴타입 메소드(...) { ... }

 

접근 제한자 생성자 설명
public 필드
메소드(...)
모든 패키지에서 필드를 읽고 변경할 수 있다.
모든 패키지에서 메소드를 호출할 수 있다.
default 필드
메소드(...)
같은 패키지에서만 필드를 읽고 변경할 수 있다.
같은 패키지에서만 메소드를 호출할 수 있다.
private 필드
메소드(...)
클래스 내부에서만 필드를 읽고 변경할 수 있다.
클래스 내부에서만 메소드를 호출할 수 있다.

 

public class A {
	//public 접근 제한을 갖는 필드 선언
	public int field1;
	//default 접근 제한을 갖는 필드 선언
	int field2;
	//private 접근 제한을 갖는 필드 선언
	private int field3;

	//생성자 선언
	public A() {
		field1 = 1; 		//o
		field2 = 1; 		//o
		field3 = 1; 		//o

		method1(); 			//o
		method2(); 			//o
		method3(); 			//o
	}

	//public 접근 제한을 갖는 메소드 선언
	public void method1() {
	}
	
	//default 접근 제한을 갖는 메소드 선언
	void method2() {
	}
	
	//private 접근 제한을 갖는 메소드 선언
	private void method3() {
	}
}

 

같은 패키지
package ch06.sec13.exam03.package1;

public class B {
	public void method() {
		//객체 생성
		A a = new A();

		//필드값 변경
		a.field1 = 1; 		// o
		a.field2 = 1; 		// o
		//a.field3 = 1;		// x

		//메소드 호출
		a.method1(); 		// o
		a.method2(); 		// o
		//a.method3(); 		// x
	}
}

 

다른 패키지
package ch06.sec13.exam03.package2;

import ch06.sec13.exam03.package1.*;

public class C {
	public C() {
		//객체 생성 
		A a = new A();
		
		//필드값 변경 
		a.field1 = 1; 		// (o)
		//a.field2 = 1; 	// (x)
		//a.field3 = 1; 	// (x)

		//메소드 호출 
		a.method1(); 		// (o)
		//a.method2(); 		// (x)
		//a.method3(); 		// (x)
	}
}

 

 

 

 

* 내용 참고 - 책 '이것이 자바다'


1.  코틀린의 특징

👩🏻‍🚀  안드로이드의 개발 환경은 Java 언어를 중심으로 확장되어 있는데, 새로운 개발 언어를 도입함

👩🏻‍🚀  Kotlin 코틀린은 2017년 안드로이드 공식 개발 언어로 지정
      ▶️ 구글이 코틀린을 안드로이드 공식 언어로 지정한 이유는 코틀린이 현대적인 언어로서 갖는 장점들 때문

👩🏻‍🚀  코틀린은 유명 IDE 제작사인 JetBrain이 만든 언어로, 같은 회사에서 만든 Intellij와 Android Studio IDE에서

       매우 잘 지원되는 언어


1) 코틀린의 장점


코틀린은 자바와 100% 상호 호환되면서도 더 현대적이고 간결 

      ▶️  자바와 코틀린 코드를 하나의 프로젝트에서 섞어서 사용할 수 있음
-  Null Pointer Exception이 발생할 수 있는 코드를 금지하고 Null에 대해 안전한 코드를 간결하게 표현 할 수 있도록 지원
'타입 추론'을 지원

      ▶️  정적 타입 지정 언어가 가진 정확성과 성능을 보장하면서도 동적 타입 언어와 같은 간결함을 유지할 수 있음
'람다 표현식'을 지원  ▶️  코틀린의 람다 표현식은 자바8부터 지원되는 람다 표현식보다 더 간결
'객체 지향' 프로그래밍과 '함수형' 프로그래밍 스타일을 모두 지원
-  코틀린의 '확장 함수'는 기존 클래스의 변경없이 클래스의 기능을 추가하는 것이 가능
-  코틀린은 이미 널리 쓰이는 '코드 패턴을 간결화할 수 있도록 설계'
      ▶️ 예를 들면 'getter', 'setter'를 묵시적으로 제공하고 자주 쓰이는 'Singleton 패턴'은 'object'로서 지원
-  코틀린의 함수는 '일급 객체'로서 다른 함수의 파라미터로 전달 가능하고 함수의 반환값을 함수 형태로 반환할 수 있어

    '높은 추상화'가 가능
-  코틀린은 '불변성을 보장하는 변수'와 '변경이 가능한 변수'를 언어 차원에서 분리
       ▶️  불변값을 갖는 변수의 사용은 '다중 쓰레드 애플리케이션 개발'에 보다 유용

 


2.  변수

👩🏻‍🚀  코틀린은 변수명을 먼저 쓰고, 콜론 : 을 쓴 후 자료형을 명시

👩🏻‍🚀  문맥상 추론이 가능하다면 자료명을 생략할 수 있음 ▶️ 코틀린의 형추론이라고 함

👩🏻‍🚀  변수명만 쓸 때는 자료형을 적어줘야 함

💡  val 변수명: 자료형 = 값
fun main() {

    val pi: Double = 3.14

    val name = "tom" // String 으로 형 추론.

    // val은 값을 변경할 수 없는 변수이므로 값을 재할당 하면 다음과 같이 컴파일 오류가 남
    // pi = 3.141593 // 오류 Val cannot be reassigned

    // 값을 변경하고 싶을 때는 var을 사용해야 됨. var로 정의된 변수는 값을 바꿀 수 있음
    var age = 21 // 형추론 Int
    println(age)  // 21
    age = 25 // 재할당
    println(age) // 25
}

 

1)  변수와 자료형


  👾  변수는 val, var 이라는 키워드를 이용하여 선언
        ⚡️  val로 변수를 선언하면 최초로 지정한 변수의 값으로 초기화하고 더 이상 바꿀 수 없는 '읽기 전용 변수'가 됨
        ⚡️  var로 변수를 선언하면 최초로 지정한 변수의 초깃값이 있더라도 '값을 바꿀 수 있음'

💡  변수를 선언한 예 :
       val username: String = "kildong"
       ➡️  변경되지 않는 변수 username이 String 자료형으로 선언되었고 "kildong"이 값으로 할당

 

  👾  코틀린은 자료형을 지정하지 않고 변수를 선언하면 변수에 할당된 값("kildong")을 보고 알아서 자료형을 지정할 수 있음

         ▶️  이것을 '자료형 추론'이라고 함
         ▶️  즉 username 변수에 "kildong"이라는 값만 할당해도 코틀린이 알아서 이 변수의 자료형을 String으로 지정
  👾  단 자료형을 지정하지 않은 변수는 반드시 자료형을 추론할 값을 지정해야 함
  👾  선언만 하고 초기화를 하지 않을 때는 반드시 자료형을 적어줘야 함

fun main() {
    val number = 10 // number 변수는 Int 형으로 추론
    var language = "Korean" // language 변수는 String으롤 추론.
    language = "English" // var 키워드로 선언한 변수는 값을 다시 할당할 수 있음
    // language = 10 // 파이썬처럼 다른 데이터 타입의 데이터는 저장할 수 없음.
    val secondNumber: Int = 20 // secondNumber 변수는 자료형을 Int로 명시적으로 지정.
    // secondNumber = 30 // val로 선언한 변수를 값을 다시 할당할 수 없음.

    println("number: $number") // 10
    println("language: $language") // English
    println("secondNumber: $secondNumber") // 20
}

 


3.  기본 자료형

👩🏻‍🚀  자료형은 크게 기본 자료형 primitive data type참조 자료형 reference data type으로 나누어 진다.
      ⚡️ 기본형은 순수하게 값을 저장하는 자료형이고 자바에서는 int, byte, boolean 등이 해당
      ⚡️ 참조형은 객체를 만들고 변수에는 객체의 참조값을 저장하고 자바에서는 String, Array 등이 해당

👩🏻‍🚀  코틀린의 자료형은 모두 참조형. 즉 모든 자료형이 객체 형태



(1) 정수 자료형  -  Byte, Short, Int, Long


   👾
  코틀린은 정수의 경우에는 숫자가 작아도 Int 형으로 추론 (기본값)

          ➡️  Byte나 Short 같은 작은 범위를 사용할 때는 자료형을 지정해야 함
 
   1)  Int : 정수


      📍  소수점이 없는 정수값을 지정할 때 사용
      📍  가독성을 높이기 위해 언더바(_)로 자릿수를 구분할 수 있음
      📍  다만, 언더바는 개발자가 읽기 쉽게 하기 위한 것으로 컴퓨터는 동일하게 인식

fun main() {    
    var intValue: Int
    intValue = 3
    intValue = 2_147_483_435
}

 


  2) Long : 정수


     📍  Int 보다 큰 범위의 정수를 저장할 수 있음
     📍  Double과 Float의 관계처럼 Int와 구분하기 위해서 숫자의 끝에 L을 붙여줌
     📍  Long 타입의 경우에는 설정한 글꼴에 따라 숫자가 1과 구분이 어려울 수 있기 때문에 대문자를 사용

fun main() {
    var longValue = 3_141592L
}

 


  3) Short와 Byte : 정수


    📍 정숫값을 저장할 때 사용하는데 입력할 수 있는 값의 크기가 Int보다 작음

fun main() {
    var shortValue: Short = 32_767
    var byteValue: Byte = 127
}

 


(2)  실수 자료형 - Double, Float


  👾  실수의 경우 자료형을 명시하지 않으면 Double 형이 됨 (기본값)

  👾  Float 형으로 지정하고 싶다면 값뒤에 F를 추가로 붙여줌

fun main() {
    val numFloat: Float = 100.0F // 자료형 생략 가능
    val numDouble: Double = 100.0 // 자료형 생략 가능
}


  1) Double : 실수 - 소수점이 있는 값을 저장할 때 사용

fun main() {
    var doubleValue: Double
    doubleValue = 3.141592
}


  2) Float : 실수


    📍 Double과 동일한 용도이지만 더 작은 범위의 숫자를 저장할 때 사용
    📍 Double과 구분하기 위해 Float의 경우 숫자 끝에 'F'를 붙여줌

fun main() {   
    var floatValue: Float
    floatValue = 3.141592F
}

 


(3) 문자 자료형


    👾  문자 자료형은 문자 하나를 표현하는 Char형과 문자열을 표현하는 String형으로 분류
    👾  Char 형은 문자를 작은 따옴표로 감싸고, String형은 문자열을 큰 따옴표로 감쌈

fun main() {
    val char: Char = 'a' // 자료형 생략 가능
    val string: String = "abc" // 자료형 생략 가능
}

(4) 논리 자료형


   👾  참, 거짓을 표현하는 true, false 를 사용하고 주로 조건 검사에 사용

fun main() {
    val isTrue: Boolean = true // 자료형 생략 가능
}

 


4.  상수  const

👩🏻‍🚀  상수는 주로 기준이 되는 변하지 않는 값을 입력해 둘 때 사용

👩🏻‍🚀  읽기 전용 변수인 val 앞에 const 키워드를 붙여서 만듦. 전역으로만 사용가능

💡  val과 같이 읽기 전용인 것은 동일하지만, 컴파일 시에 값이 결정되기 때문에 Int, Long과 같은 기본형과 문자열인 String만 입력할 수 있음
const val PI = 3.141592653589793

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]

+ Recent posts