Dev/Java

[java] static변수, 변수 초기화 방법, Overloading

창문닦이 2019. 1. 22. 13:33

static변수


public class Data {

static String name = "배수지"; //static변수이므로 이미 메모리 할당되어 있음

static int age = 25;

public static void print(){

System.out.println(name +"의 나이는 "+ age +"살입니다.");

//현재상태에서는 오류 없으나, 배수지와 25가 static변수가 아니면 오류발생함. 메모리 할당 안해준것.

}

}


전역변수는 반드시 메모리를 다른곳에 저장하고 메소드만 동일 주소로 사용함을 볼 수 있는 예제


class IntClass{//int값 두개를 저장할 수 있는 클래스. 클래스 자체를 자료형이라고 생각. 클래스=저장소로 기억하면 편함

//변수선언만 진행

int a;

int b;

}

public class Test1 {

public static void main(String[] args) {

IntClass ob1 = new IntClass(); //new로 객체를 생성한 전역변수는 초기값이 들어있음. int형이므로 0

IntClass ob2 = new IntClass();

//인스턴스변수는 반드시 메모리를 다른곳에 저장하고

//메소드만 동일 주소로 사용함을 볼 수 있는 예제

ob1.a=10;

ob1.b=20;

System.out.println("ob1.a:"+ob1.a); //10

System.out.println("ob1.b:"+ob1.b); //20

System.out.println("-------------");

System.out.println("ob2.a:"+ob2.a); //0

System.out.println("ob2.b:"+ob2.b); //0

System.out.println("-------------");

ob2.a=100;

ob2.b=200;

System.out.println("ob2.a:"+ob2.a); //100

System.out.println("ob2.b:"+ob2.b); //200

System.out.println("-------------");

System.out.println("ob1.a:"+ob1.a); //10

System.out.println("ob1.b:"+ob1.b); //20

}

}


변수초기화 방법 : '=' 이용해서 직접 대입

 .set()메소드 활용

Circle ob = new Circle(); 객체생성

ob.setData(10); 매개변수 10으로 setData메소드를 실행해라.

우회해서 변수에 값을 넣는 것. private의 경우 반드시 이런 메소드가 있어야 한다.


this : me. class 이름


코딩하다보면 연결이 끊어진 garbage 데이터가 존재하는 경우가 있음

VM에서 이런 클래스들을 삭제하는 garbage collector가 존재함

그런데 메소드가 따로 없기 때문에 돌아다니다 자동으로 삭제되므로 하나도 삭제를 못하는 경우도 존재


import java.util.Scanner;

class Circle{

private int r; //instance변수. 중간에 값을 변경할 수 있으니까 외부에서 접근하지 못하게 접근지정자 작성.

 //private : within the class

 //아무것도 쓰지 않으면 public

 //정보의 은닉(캡슐화)


//초기화 메소드. 매개변수 이용. private 변수의 경우 이 메소드가 반드시 필요함

public void setData(int r){//setData(int r, Circle this) 내부적으로는 이렇게 처리됨

this.r = r; //전역변수 r, 지역변수 r 이름이 동일하면 구분못함

//컴퓨터에서 전역변수로 인식하게 하기 위해 this사용. this는 me 와 같음. 자기자신. 클래스이름의 대명사.

//혼동될 소지가 없으면 생략해도 됨

}

public double area(){//area(Circle this)

return this.r*this.r*3.14;

}

public void write(double a){//write(double a, Circle this)

System.out.println("반지름:" + this.r);

System.out.println("면적:" + a);

}

}

public class Test2 {

public static void main(String[] args) {

Circle c1 = new Circle();

//c1.r = 100; 캡슐화 되어있어 외부에서 접근할 수 없다. 실행하면 오류남

Scanner sc = new Scanner(System.in);

System.out.print("반지름을 입력하세요: ");

int r = sc.nextInt();

c1.setData(r); //c1.setData(r,c1); 내부적으로 c1클래스의 주소를 가져감

double result = c1.area(); //c1.area(c1); 매개변수 없으므로 c1클래스의 주소만 가져감

c1.write(result); //c1.write(result,c1);

}

}



static : 자신이 알아서 로딩만 하게 되면 메모리에 올라가 있다.

new를 통해서 객체를 생성하면 메모리에 올라감. static은 new를 쓰지않아도 알아서 올라감

1. 자동으로 메모리 할당을 받는다.

2. 객체를 100번 생성해도 메모리공간은 하나만 생성된다. 모든 사람이 공동으로 사용한다라고 생각


public class Test3 {

//static을 줌으로써 클레스가 로딩되는 순간 메모리상에 이미 올라가있음 int a 와 print()

//논리적으로 같은 클래스안에서 선언해뒀지만

//int b와 write()는 메모리상에 올리지 않아서 실행 불가

public static int a = 10;

//class변수. 자신이 알아서 메모리에 올라감

//static 변수의 특징

//클래스가 로딩되는 순간 메모리에 할당 되어진다.

//접근방법 : [클래스이름.변수명] 으로 접근한다

//즉, new를 통해서 메모리 할당을 받지 않아도 사용이 가능하다.

private int b = 20;

//instance변수. 메모리에 올라가야만 사용할 수 있다.

//메모리에 올라가기 위해서는 내가 객체 생성을 해주어야 함

//반드시 new를 통해서 메모리 할당을 받아야 사용 가능하다

//동일 클래스 메소드에서 접근이 가능하다

//-> write();가 실행시켜지기 위해서는 메모리에 로딩을 하게되는데 그때 동시에 int b도 같이 로딩되므로 가능

//클래스메소드에서는 접근이 불가능하다.

//-> 메모리상에 이미 올라가 있는 class 메소드에서 instance변수를 찾게되면 아직 메모리에 로딩되지 않아 찾지 못하기 때문

public void write(){//instance메소드. 클래스변수와 인스턴스변수를 모두 사용가능.

System.out.println("class 변수 a: " + a);

System.out.println("instance 변수 b: "+ b);

}

public static void print(){//class메소드. 이미 메모리상에 올라가 있기 때문에 static변수만 사용할 수 있음

System.out.println("class 변수 a: " + a);

//System.out.println("instance 변수 b: "+ b);

}

public static void main(String[] args) {

System.out.println("main...");

System.out.println("class 변수 a: " + a);//class변수는 객체를 생성하기 전에 올라가므로 ob.a로 호출하지 않음.클래스의 이름으로 붙여줌

System.out.println("class 변수 a: " + Test3.a); //여기다가 this 쓰면 안됨. 이건 class변수.

//System.out.println("instance 변수 b: "+ ob.b); 객체생성이 먼저 일어난 후에 메소드 실행 가능

//write(); 오류

print(); //static이므로 가능

Test3.print(); //이렇게 호출해주는게 좋음. class메소드

Test3 ob = new Test3(); //객체생성. 이렇게 되는 순간 instance메소드와 instance변수가 메모리상에 올라감

System.out.println("instance 변수 b: "+ ob.b);

ob.write();

System.out.println("class 변수 a: " + ob.a); // 에러는 아니지만 클래스변수를 객체변수로 쓴 것...

ob.print();

Test3 ob1 = new Test3();

ob1.a = 100; // 10 -> 100

ob1.b = 200; // 따로 만들어지므로 ob.b 와 ob1.b 메모리는 다름

System.out.println("------------------------");

System.out.println("ob1.a:"+ ob1.a);

System.out.println("ob1.b:"+ ob1.b);

System.out.println("------------------------");

System.out.println("ob.a:"+ ob.a);//100  static은 오로지 같은 공간이기 때문에 같이 사용함. 10에서 100으로 바뀌어져 있음

System.out.println("ob.b:"+ ob.b);//20

System.out.println("------------------------");

ob.a=500;

System.out.println("ob1.a:"+ ob1.a); //ob1.a 와 ob.a의 저장공간은 같다. 같이 사용한다. static이기 때문

System.out.println("ob.a:"+ ob.a);

}

}


Calendar 현재시점의 날짜와 시간을 이용하는 클래스. static class. new 로 만들 수 없음


import java.util.Calendar;

public class Test4 {

public static void main(String[] args) {

Data ob = new Data(); //객체생성

ob.print();

Data.print(); //클래스이름.메소드명

//위에 두줄을 이처럼 하나로 바로 호출 가능. 미리 메모리상에 올라가있는 static 메소드

//Calendar now = new Calendar();

Calendar now1 = Calendar.getInstance(); //언제 호출해도 같은 값. 굳이 똑같은 값을 여러개 만들어 메모리 낭비할 필요 없음.

}

}


Overload(Overloading : 메소드 중복정의)


class Rect{//전부 instance변수와 instance메소드

private int w,h ; //전역변수, instance변수

public void set(int w, int h){ // 전역변수와 매개변수의 이름이 똑같아서 혼란이 옴. 이럴때 this 사용

//우회해서 초기화 시킬 수 있도록함. 초기화메소드

this.w= w;

this.h= h;

}

public int area(){

return w*h;

}

public int length(){

return (w+h)*2;

}

public void print(int a, double l){

System.out.println("가로: "+w+", 세로: "+h);

System.out.println("넓이: "+a+", 둘레: "+l);

}

// Overload(Overloading : 메소드 중복정의)

// 조건: 같은 클래스안에서 메소드의 이름은 동일하지만 매개변수의 갯수나 자료형은 달라야 한다. -> 다른 메소드로 인식한다.

// 메소드이름같고, 매개변수갯수같고, 자료형도 같다면 같은 메소드로 인식

// 왜 존재? 같은 역할을 하는 메소드를 통일시키기 위해서

public void print(){

System.out.println("가로: "+w+", 세로: "+h);

}

public void print(int a){ //매개변수1개

System.out.println("가로: "+w+", 세로: "+h);

System.out.println("넓이: "+a);

}

public void print(double l){//매개변수1개. 자료형 다름

System.out.println("가로: "+w+", 세로: "+h);

System.out.println("둘레: "+l);

}

}

public class Test5 {

public static void main(String[] args) {

Rect ob1 = new Rect();

ob1.set(10,20); //w,h에 초기화시킴

int a = ob1.area();

double l = ob1.length();

ob1.print(a,l);

ob1.print();

ob1.print();

//ob1.printt(l);얘는 메소드이름이 다르기 때문에 overloading 이 아니다.

//String str;

//str.valueof(); 같은 메소드명으로 9개 존재. 모두 자료형 다름

}

}


[문제1]

System.in.read()만 사용해서 숫자를 입력받고

입력받은 수까지의 합계를 구하시오

조건

1.BufferedReader X

2.Scanner X

모양

수입력? 10

1-10까지의 합: 55

import java.io.IOException;

public class Test6 {

public static void main(String[] args) throws IOException {

/*

//방법1

char ch = 0;

   String str = "";

  

int sum, i , j ;

sum = i = 0;

System.out.print("숫자를 입력하세요: ");

while (true) {

ch = (char) System.in.read();

for (i = 0; i <= 9; i++) {

if (ch % 48 == i) {

str = str + ch;

}

}

if (ch == 13) {

break;

}

}

j = Integer.parseInt(str);

for(i=0;i<=j;i++){

sum = sum + i;

}

System.out.printf("1부터 %d까지의 합계는 %d 입니다.",j, sum);

*/

//방법2

int n=0, s=0;

int data;

System.out.print("숫자를 입력하세요: ");//1(49)2(50)3(51)

//System.in.read() 사용자가 입력한 숫자를 byte단위로 읽어서 저장함

while((data=System.in.read())!=13){

n=n*10+data-48; //char형태의 값을 정수로 변환.

}

// 1 = 0 * 10 + 49 - 48

// 12 = 1 * 10 + 50 - 48

// 123 = 12 * 10 + 51 - 48

for(int i=1;i<=n;i++){

s = s + i;

}

System.out.printf("1부터 %d까지의 합계는 %d 입니다.",n,s);

}

}


[문제2] 인원수를 입력 받아 인원수만큼 과목별 점수를 입력하고 각 과목별 판정을 하시오 인원수 : 2 1번째 이름 :전지현 국어 ? : 100 영어 ? : 100 수학 ? : 100 2번째 이름 :옥주현 국어 ? : 80 영어 ? : 80 수학 ? : 80 전지현 100(수) 100(수) 100(수) 300 100 옥주현 80(우) 80(우) 80(우) 240 80

import java.util.Scanner;

class Record {

String name;

String[] level = new String[3];

int[] score = new int[3];

int tot, ave;

}

class Score {

int inwon;

Record[] rec;

Scanner sc = new Scanner(System.in);

String[] title = { "국어", "영어", "수학" };

public void set() {

do {

System.out.print("인원수?");

inwon = sc.nextInt();

} while (inwon < 1 || inwon > 10);

rec = new Record[inwon];

}

public void input() {

for (int i = 0; i < inwon; i++) {

rec[i] = new Record();

System.out.print("이름?");// 이름

rec[i].name = sc.next();

for (int j = 0; j < 3; j++) {

System.out.print(title[j]);

rec[i].score[j] = sc.nextInt();// 국영수

rec[i].tot += rec[i].score[j];// 총점

}

rec[i].ave = rec[i].tot / 3;// 평균

}

}

public void print() {

for (int i = 0; i < inwon; i++) {

System.out.printf("%d번째 이름 %6s", i+1, rec[i].name);

for (int j = 0; j < 3; j++) {

System.out.printf("%s:%d%s  ", title[j],  rec[i].score[j],rec[i].level[j]);

}

System.out.printf("총점:%d  ", rec[i].tot);

System.out.printf("평균:%d  ", rec[i].ave);

System.out.println();

}

}

public void pan() {

for (int i = 0; i < inwon; i++) {

for (int j = 0; j < 3; j++) {

if (rec[i].score[j] == 100 || rec[i].score[j] >= 90) {

rec[i].level[j] = "(수)";

} else if (rec[i].score[j] >= 80) {

rec[i].level[j] = "(우)";

} else if (rec[i].score[j] >= 70) {

rec[i].level[j] = "(미)";

} else if (rec[i].score[j] >= 60) {

rec[i].level[j] = "(양)";

} else {

rec[i].level[j] = "(가)";

}

}

}

}

}

public class Test7 {

public static void main(String[] args) {

Score ob1 = new Score();

ob1.set();

ob1.input();

ob1.pan();

ob1.print();

}

}