(1) 수정자 (modifier)
1.abstract : 추상 (class, method)
2.final : 변수, 메소드, 클래스에 모두 사용
variable : 변수에 final을 붙이게 되면 상수화(변수 변경 불가)가 된다.
public class FinalVarTest {
private final int x; //error : final을 붙였기 때문에 상수화
public void changeX() {
x=10;
}
}
---------- compile ----------
FinalVarTest.java:5: error: cannot assign a value to final variable x
x=10;
method : 메소드에 final을 붙이게 되면 상속후에도 override가 불가능하다.
public class FinalMethodTest {
public final void x() {} //final method
}
public class FinalMethodExt extends FinalMethodTest {
public final void x(){} //final method는 override 불가
}
---------- compile ----------
FinalMethodExt.java:3: error: x() in FinalMethodExt cannot override x() in FinalMethodTest
public final void x(){} //final method는 override 불가
class : 클래스에 final을 붙이게 되면 상속이 불가능하다.
public final class FinalClassTest {
}
//final class는 상속 불가능!!
public class FinalClassExt extends FinalClassTest {
public static void main(String[] args) {
System.out.println();
}
}
---------- compile ----------
FinalClassExt.java:3: error: cannot inherit from final FinalClassTest
public class FinalClassExt extends FinalClassTest {
3.static : 공유 (객체 생성하지 않아도 클래스의 이름으로 접근 가능), class 변수라고 한다.
> 클래스 변수 : static한 변수, 값을 저장할 수 있는 공간이 하나밖에 없어서 값을 공유한다.
> 인스턴스가 여러개 생성되어도 static 변수는 딱 하나이다.
공용적인 데이터, 동일한 값, 고정 값 등
사용 ) 클래스의 이름.변수이름
VS
instance 변수 : 각자의 객체를 참조해야 접근 할 수 있는 변수, 객체 생성 필요
객체마다 가지고 있어야 할 데이터, 변화 가능한 객체들의 특징
사용) 객체의 이름. 변수이름
variable : static을 붙일 수 있다.
method : static을 붙일 수 있다.
class : static을 붙일 수 없다. (단, inner class에서는 가능)
class A {
class B {
}
}
Q. static 블록과 메소드에서 instance 필드나 메소드를 사용하고 싶다면??
> 객체를 생성해서 사용 가능하다!! or 필드나 메소드에 static 붙이기
* static이 선언되지 않은 변수와 메소드는 static 블록내(main method)에서 사용 불가능
(but, static 블록이 아닌 다른 블록 내에서는 static 변수와 메소드가 사용 가능!!!)
Static(공유)
y
|
class 변수
A
|
Heap
(동적할당)
x=10
y
----------
x
y=20
|
instance 변수
|
Stack
a1 a2
|
|
a1.x = 10;
S.o.p(a2.x); //0
a2.y = 20; -----------A.y = 20;
S.o.p(a1.y); //0 ------S.o.p(A.y); //20
* static과 객체와의 관계
> static은 클래스 변수다.
> 객체는 클래스에서 생성(복사) 되어진다.
> 클래스 하나에서 무한대로 객체를 생성할 수 있지만, 독립적인 전혀 다른 덩어리들이다.
> static이 붙은 변수는 클래스 변수로써 객체가 생성되기 전에 이미 존재한다.
클래스들이 모여 있는 데이터 영역 (new로 객체 생성하기 전)
객체들이 모여 있는 Heap 영역(new로 객체 생성) ----> 가비지 콜렉터는 Heap 영역만 메모리를 관리한다.
*설명
|
variable
|
method
|
class
|
abstract
|
x
|
o
|
o
|
final
|
o
|
o
|
o
|
static
|
o
|
O
|
X
(but,
inner class o)
|
4. 상수 : 상수이기 때문에 초기화 필요 (한 번 값을 초기화하면 변경 불가), 대문자로 작성하는 것이 관례
초기화 방법 )
1. 처음 선언에서 초기화 하기
static final DataType CONSTANCE_NAME = 값;
2. static 블록에서 초기화 하기 (복잡한 초기화 식이 있을 때)
static final DataType CONSTANCE_NAME;
static{
상수 = 초기값;
final 필드
|
static final (상수)
|
instance 필드
|
정적 필드
|
생성자에서 초기화 될 수 있다.
|
생성자에서 초기화 될 수 x
* 생성자를 생성하는 것 자체가 객체를 생성하는 것이기 때문에 상수는 객체를 생성하기 전에
이미 완성이 되어 있어야 한다!!
(선언할 때 or 정적 블록에서 초기화 되야 함)
|
|
대문자로 작성, 합성어인 경우 _로 구분
|
|
객체 생성없이 클래스를 통해 사용
|
초기값이 저장되면 값을 변경할 수 없다.
|
- 포인트 적립 ex) 객체 따로따로 counting...
public class PointCard {
String name;
int count;
public PointCard(String name){
this.name = name;
}
public void buy(){
count++;
}
}
public class PointStore {
public static void main(String[] args) {
PointCard pc1 = new PointCard("홍길동");
PointCard pc2 = new PointCard("임꺽정");
System.out.println(pc1.name + "님 구매!!!");
pc1.buy();
System.out.println("스탬프 : " + pc1.count + "개");
System.out.println(pc2.name + "님 구매!!!");
pc2.buy();
System.out.println("스탬프 : " + pc2.count + "개");
System.out.println(pc1.name + "님 구매!!!");
pc1.buy();
System.out.println("스탬프 : " + pc1.count + "개");
System.out.println(pc2.name + " 스탬프 확인 : " + pc2.count + "개");
}
}
---------- run ----------
홍길동님 구매!!!
스탬프 : 1개
임꺽정님 구매!!!
스탬프 : 1개
홍길동님 구매!!!
스탬프 : 2개
임꺽정 스탬프 확인 : 1개
- 위의 코딩에 static만 추가해 본다면?? '누적' 방문객 수를 출력할 수 있다!! (공유), 객체 생성하지 않고!!
> 하나의 변수이기 때문에 값이 계속 누적!!
public class Guest {
String name;
static int count; //방문횟수
public Guest(String name){
this.name = name;
}
public static void visit(){
count++;
}
}
public class Store {
public static void main(String[] args) {
System.out.println("손님 방문!!!");
Guest.visit();
System.out.println("방문자수 : " + Guest.count + "명");
System.out.println("손님 방문!!!");
Guest.visit();
System.out.println("방문자수 : " + Guest.count + "명");
System.out.println("손님 방문!!!");
Guest.visit();
System.out.println("방문자수 : " + Guest.count + "명");
}
}
---------- run ----------
손님 방문!!!
방문자수 : 1명
손님 방문!!!
방문자수 : 2명
손님 방문!!!
방문자수 : 3명
ex) 객체 생성하지 않고 호출하기
public class Printer{
static void printin(int a){
System.out.println(a);
}
static void println(boolean a){
System.out.println(a);
}
static void println(double a){
System.out.println(a);
}
static void println(String a){
System.out.println(a);
}
}
public class PrinterExample {
public static void main(String[] args) {
Printer.println(10);
Printer.println(true);
Printer.println(5.7);
Printer.println("홍길동");
}
}
(2) 배열 (Array) -- 반복문과 단짝!!!!
장점 : 서로 연관된 데이터를 정리정돈 !!
(* 변수가 많을수록 오류 or 혼동 가능성이 있기 때문에 서로 연관된 데이터는 하나의 배열 변수로 만들어 주는 것이 좋다!!!!)
1.같은 DataType의 여러 개의 값을 연속적으로 저장.
2.배열은 생성시 크기를 반드시 지정 >> 한 번 정해진 배열의 크기는 변할 수 없다..
>> 배열의 크기 : int size = 배열명.length;
3.기본DataType을 저장하는 reference 배열의 사용
a. 선언
형식) 접근제어자 기본DT[ ] 배열명;
or
접근제어자 기본DT 배열명[ ]; (둘 다 똑같지만, 이 형식을 더 많이 사용)
ex)
public int x[ ];
private boolean b[ ];
b.생성
형식) 배열명 = new 기DT[크기];
ex)
x = new int[3]
b = new boolean[2];
>> a, b를 동시에 가능!!
접근제어자 기DT 배열명[ ] = NEW 기DT[크기];
public int x[ ] = new int[3];
private boolean b [ ]= new boolean[2];
c. 사용 : 값 할당
형식)
get : 배열명[index];
set : 배열명[index] = 값;
ex)
int x1 = 10;
int x2 = 30;
int x3 = 30;
>>> 배열
x[0] = 10;
x[1] = 20;
x[2] = 30;
S.o.p(x[0]);//10
S.o.p(x[1]);//20
S.o.p(x[2]);//30
or
int len = x.length;
for(int i=0;i<len;i++) {
x[i] = (i+1) * 10;
S.o.p(x[i]);
}
>> a,b,c를 동시에..
ex)
public int x[] = {10,20,30};
public class ArrayTest1 {
public static void main(String[] args) {
int x1 = 10;
int x2 = 20;
int x3 = 30;
System.out.println("x1 : " + x1 + " x2 : " + x2 + " x3 : " + x3);
int x[] = new int[3];
x[0] = 10;
x[1] = 20;
x[2] = 30;
System.out.println("x[0] : " + x[0] + " x[1] : " + x[1] + " x[2] : " + x[2] );
int y[] = new int[3];
int len = y.length;
for (int i=0;i<len ;i++ ){ //규칙이 있다면 for문 사용
y[i] = (i+1)*10;
System.out.print(" y[" + i + "] : " + y[i]);
}
System.out.println();
int z[] = {10,20,30,40};
len = z.length;
for (int i=0;i<len ;i++ ){
System.out.print(" z[" + i + "] : " + z[i]);
}
}
}
---------- run ----------
x1 : 10 x2 : 20 x3 : 30
x[0] : 10 x[1] : 20 x[2] : 30
y[0] : 10 y[1] : 20 y[2] : 30
z[0] : 10 z[1] : 20 z[2] : 30 z[3] : 40
/*
정수형의 5개의 배열을 만드시오.
1-10까지의 수 중 짝수만 저장.
출력.
*/
public class ArrayTest2 {
public static void main(String[] args) {
int x[] = new int[5];
int idx = 0;
for (int i=1;i<=10 ;i++ ){
if (i%2==0){
x[idx++] = i; //x[]에 i를 대입해라
}
}
int len = x.length;
for (int i=0;i<len ;i++ ){
System.out.println(x[i]);
}
}
}
/*백준 알고리즘 배열 문제 (음계)
int x[] = {1,2,3,4,5,6,7,8}; -- ascending
int x[] = {8,7,6,5,4,3,2,1}; -- descending
int x[] = {8,1,7,2,6,3,5,4}; -- mixed
*/
public class ArrayTest3 {
public static void main(String[] args) {
int x[] = {1,2,3,4,5,6,7,8};
//int x[] = {8,7,6,5,4,3,2,1};
//int x[] = {8,1,7,2,6,3,5,4};
/*int len = x.length;
int idx = 0;
for (int i=1;i<len ;i++ ){
if (x[0]<x[1]){
x[idx++] = i;
System.out.println("ascending");
}
if (x[0]>x[1]){
x[idx++] = i;
System.out.println("descending");
} else {
System.out.println("mixed");
}
}*/
int len = x.length;
int a = 0;
int d = 0;
String str = "mixed";
for(int i=1;i<len;i++) { //배열의 길이는 8, 서로 비교해야 하니까 0이 아닌 1부터 시작!!
if(x[i-1] < x[i])
a++;
if(x[i-1] > x[i])
d++;
}
if(a == 7)
str = "ascending";
else if(d == 7)
str = "descending";
System.out.println(str);
}
}
4. for each문 : 값을 꺼내서 알아서 대입해 준다. for문 보다 훨씬 간결해진다.
for(타입 값을 받아줄 변수명 : 출력하고 싶은 자료구조)
//for each문을 이용해서 iarr의 값을 한 줄씩 출력하라.
public class Array1 {
public static void main(String[] args) {
int[] iarr = {10,20,30,40,50};
for (int i=0;i<iarr.length ;i++ ){
int value = iarr[i];
System.out.println(value);
}
//System.out.println(value); //반복된 후 마지막 값인 50만 출력됨.
for (int value : iarr){
System.out.println(value);
}
}
}