[JAVA] Day 9 - 생성자 / Static / Stack / Heap영역 / Overloading(오버로딩)

sue·2023년 11월 24일

📒국비학원 [JAVA]

목록 보기
6/20
post-thumbnail
  • 기본 생성자

public TestImpl() 	
	}
  • 생성자 오버로딩 (생성과 동시에 값을 초기화시킴)

public TestImpl (String hak,String name,int kor,int eng) {
		this.hak = hak;
		this.name = name;
		this.kor = kor;
		this.eng = eng;
	}
  • 기본 생성자(생성자오버로딩x) + public void set( ) 메서드 만들기

    why?
    나중에 객체의 데이터값을 변경(값 초기화)해주고싶으면, private때문에 우회접근이 필요하니까
    ② 외부에서 객체의 데이터를 변경하려면, set 메서드와 같은 메서드를 제공
public void set(String hak,String name,int kor,int eng) {
		this.hak = hak;
		this.name = name;
		this.kor = kor;
		this.eng = eng;
	}

JVM(Java Virtual Machine)의 메모리 구조 (자바 -> os실행할 때)

나누는 이유 : 메모리 공간을 효율적으로 하기 위해

  • Static :
    ① 메모리에 끝까지 남아있음. static이 붙은건 항상 올라가있음. static이 안 붙어있는 친구들은
         new라는 엘레베이터를 타고 static영역으로 올려야함
    ② 객체를 아무리 많이 실행해도 메모리 공간은 한번만 실행됨.
    → new를 만나 [객체생성] 다시 처음으로 올라와서 실행해도, 이미 한번 자동으로 먼저 올라왔었으므로 메모리 실행 x
    변수를 선언 하게 되면 ** 모든 사람들이 다 쓸 수 있음.

  • Stack : 메서드가 실행 { 하면 stack영역이 열림 (지역변수,매개변수 해당)-> } 소멸,닫힘 ( 닫힌 이후에 이 안에서만 사용 가능, 밖으로 가지고 나가면 에러 발생 / ex) 메모리 할당할 때 - Record re <-이 부분 해당 = new Recor();

  • Heap : ex) 메모리 할당할 때 - Record re = new Record(); <-이 부분 해당

🔎 [Eclipse] - [package] - [class] 생성


📌 Note Code


  • instance 변수 = 전역변수/ [new]를 만나야지 메모리에 저장가능 = '초기값 0' (메모리 할당,객체생성)

Test1. 이름과 나이 출력하시오

💻 입력 [ Mydata ] - main메소드 x

import java.util.Scanner;

public class Mydata {
	
	static String name = "배수지"; //instance 메소드 -> new를 만나야 메모리에 올라가게 됨
	static int age = 27;
	
	public static void getInstance() { // getInstance = 이미 만들어진 
		System.out.println(name+"의 나이는 "+age+"살 입니다");
	}
}

💡 **출력**
main 출입문이 없기때문에 출력이 나올 수 없다



📌 Note Code


  • class 내부 : 변수 / 메소드 로 이루어짐.
  • private 쓰는 이유 : ① 외부에서 못가져오게 하거나 ② 중간에서 값 못바꾸게 하고 싶을 때
    → 그래서 이 땐, 메소드() this.를 사용해서 우회도로 를 만들어 주어야 함.
  • 일반적으로 많이 사용하는 메소드의 이름 = setData / getData
    → ① setData : 데이터 값 ex) int r 을 준다. ex) public void setData(int r) { this.r = r; }
    → ② getData : 데이터 값을 받는다. -> return 필요! ex) public int getData(){ return this.data; }
  • this.변수 : ex) this.r =r일 때, r은 서로 같지 않음.
    → 원래 this. ['class 이름'의 데이터 값] 는 다 있지만 혼동하지 않을 때에는 생략함.
  • 메소드( ) 생성할 때 반환(return)값 받고 싶으면, 자료형으로 메소드 만들어야 함 (void x)
    → 위 retrun 값을 다음 메소드 (매개변수 = 반환값과 타입일치시켜주고 + 아무 변수 이름 만듬)
  • main 메소드 에서는 반드시 클래스의 복사본 [new]를 만들어주어야 함. ex) Circle cc = new Circle() ;
    그래야 위에 메모리 공간에 안올라와 있는 class들을 가져다가 쓸 수 있음.
  • 값을 출력할 때, return값이 있었던 메소드는 ' 타입 + 돌려받을 변수명(아무거나 가능) = cc. return값이 있었던 메소드() ; '으로 가능
  • 위의 값을 받아 cc.메소드명(돌려받을 변수명(아무거나 가능)) 출력
  • 같은 출력값을 두번 이상 반복시 > 출력할때 쓰는 자료형은 빼주자!

Test2. 원의 넓이와 반지름 길이를 구하여라

💻 입력

//this = class 이름  ex) this = Circle의 r값


class Circle{ //class 내부 - 1)변수, 2)메소드
	
	//인스턴스 변수 = 초기값 0
	private int r; //private - 아래와 같이 우회도로 만들기
	
	public void setData(int r){//setData(Circle this,int r)
		// 데이터 넣는다 = setData, 데이터 받는다 = getData
		this.r = r; // 변수 같은 이름으로 하면 local 변수라서 밖으로 나갈 수 없으므로 int r값 받아서 r=r이 됨
	}
	
	
	//area(Circle this)
	public double area() {//해당 메소드는 this. = 혼동이 안되므로 생략하고 써도됨
		
		return r*r*3.14;
	}
	
	
	public void write(double a) {//write(Circle this,double a)
		System.out.println("반지름: "+this.r);
		System.out.println("넓이: "+ a);
	}
	
}


public class Test1 {

	public static void main(String[] args) {

		Circle ob = new Circle();
		
		ob.setData(50);//ob.setData(ob의 50번지);
		double result = ob.area(); //result값은 변경해도 됨 //area(ob)
		ob.write(result);//write(ob,result)
		
		System.out.println();
		
		ob.setData(10);
		result = ob.area(); //재활용할땐 double삭제
		ob.write(result);
	}

}

💡 **출력**
반지름: 50
넓이: 7850.0

반지름: 10
넓이: 314.0


📌 Note Code


  • 인스턴스 메서드 (instance method)
    ① 객체 생성 -> 참조변수, 메서드 이름() 호출
    ② 인스턴스 변수 관련 작업을 하는 메서드
    ③ 메서드 내 인스턴스 변수 사용 가능
    ④ 동일한 클래스의 메소드에서 접근이 가능하지만 클래스 메소드에서는 접근이 불가능함
    ⑤ 인스턴트 변수 (= Non-Static Field) : 객체마다 다른 변수값을 가짐

  • 클래스 메서드(class method)
    ① 객체 생성 없이 X -> 클래스이름.메서드이름() 호출
    ② 인스턴스변수 or 인스턴스 메서드와는 상관없는 작업을 하는 메서드
    ③ 클래스 메서드 내에서 인스턴스 변수 사용 불가
    ④ 출력시 - 클래스이름.변수도 가능
    ⑤ 클래스 변수 (= Static Field) :

[출처-하유의 리뷰월드]

  • class 변수 : method 앞에 static 이 붙은 것 / 클래스가 코딩(run)되는 순간 메모리 변경 ex) public static int x = y;
  • 모든 메소드나 인스턴스에서 동일한 값으로 갖게됨
  • 클래스에 따라서 만들어진 모든 인스턴스들은 그 클래스 변수가 가진 값을 자연스럽게 갖고있음
  • 접근방법 : [클래스이름, 객체이름]으로 접근 가능
  • 굳이 new를 통해 메모리 할당 x
  • 자바에서 들어눕는 이탤릭체 abc 한번 들여다볼 필요는 있음.

Test3. private값 초기화해서 출력하는 법

💻 입력

package com.day9;


public class Test2 {
	
	public static int a = 10; //자바에서 들어눕는 애 = 이탤릭체 static ex) a
	
	private int b = 20;//instance 변수
	
	public void write() { //instance 메서드 - 반드시 객체생성
		
		System.out.println("class 변수: "+a);
		System.out.println("instance 변수: "+b);
		
	}

	public static void print() {//class 메서드 
		System.out.println("class 변수: "+a);
		//System.out.println("instance 변수: "+b); 에러 ? class메서드에서는 instance 메서드 호출 불가 

	}
	
	
	public static void main(String[] args) {

		System.out.println("class변수 : "+a);
		//System.out.println("instance 변수: "+b);
		System.out.println("class변수 : "+Test2.a); //클래스 변수 = static 변수라는걸 알기위해
		
		//write(); 메모리 - static에 안올라가있음
		print(); //메모리 - static에 올라가있음
		
		Test2.print(); // = ob.print();
		
		
		//new를 통해 엘베타고 가야 메모리상에 올라감
		Test2 ob = new Test2(); //자기자신의 객체 생성 가능
		System.out.println("instance 변수: "+ob.b);
		System.out.println("class변수 : "+ob.a);
		ob.write();
		
		
		System.out.println("------------------------");
		Test2 ob1 = new Test2();
		ob1.a = 100;
		ob1.b = 200;
		
		ob.write();
		ob1.write();
		
		
		System.out.println("------------------------");
		Test2 ob2 = new Test2();
		ob.write();
		ob1.write();
		ob2.write();
	
	
		//static 변수 : 보수가 편리함. 
	}
}

💡 **출력**
class변수 : 10
class변수 : 10
class 변수: 10
class 변수: 10
instance 변수: 20
class변수 : 10
class 변수: 10
instance 변수: 20
------------------------
class 변수: 100
instance 변수: 20
class 변수: 100
instance 변수: 200
------------------------
class 변수: 100
instance 변수: 20
class 변수: 100
instance 변수: 200
class 변수: 100
instance 변수: 20


📌 Note Code


  • 메소드 오버로딩(overloading) = 메소드 중복정의
    하나의 클래스 안에서 하는 일이 비슷한 메소드의 이름을 통일시키는 작업
    ② 메소드의 이름은 통일시키고 매개변수의 개수나 자료형이 다르면 다른 메소드로 인식함

Test4. 사각형의 넓이와 둘레 구하기

💻 입력


import java.util.Scanner;

class Rect {

	private int w, h;

	public void set(int w, int h) {
		this.w = w;
		this.h = h;
	}

	public int area() {
		return w * h;
	}

	public int length() {
		return (w + h) * 2;
	}

	public void print(int a, int l) { // 위에 반환값이 있으면 매개변수 안에 넣어줘야함

		System.out.println("가로 : " + w);
		System.out.println("세로 : " + h);
		System.out.println("넓이 : " + a);
		System.out.println("둘레: " + l);
	}

	// print로 변수 이름은 같으나 매개변수 안 자료형 다 다름 - overloading (오버로딩)

	public void print() {

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

	public void print(int a) {
		System.out.println("가로 : " + w);
		System.out.println("세로 : " + h);
		System.out.println("넓이 : " + a);
	}

	public void print(double l) {
		System.out.println("가로 : " + w);
		System.out.println("세로 : " + h);
		System.out.println("둘레: " + l);
	}

}

public class Test4 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		Rect ob = new Rect();

		int w, h;

		System.out.print("가로?");
		w = sc.nextInt();

		System.out.print("세로?");
		h = sc.nextInt();

		System.out.println();
		 
		ob.set(w, h);
		int a = ob.area();
		int l = ob.length();

		ob.print();
		System.out.println();
		ob.print(l);
		System.out.println();
		ob.print(l);
		System.out.println();
		ob.print(a, l);

	}

}

💡 **출력**
가로?10
세로?20

가로 : 10
세로 : 20

가로 : 10
세로 : 20
넓이 : 60

가로 : 10
세로 : 20
넓이 : 60

가로 : 10
세로 : 20
넓이 : 200
둘레: 60


📌 Note Code


  • 원래 기본 생성자가 생략되어 있음. -> [new]객체생성시 기본 생성자 생성필수
  • 생성자
    ① 메모리를 할당 받을 때 사용 = 객체생성
    클래스의 이름과 같음
    리턴값이 없기때문에 property(ex) void,int 등)가 없음
    ④ 오버로딩이 가능함 -> 오버로딩 시, 기본생성자 생성필수
    변수 초기화
    ⑥ 생성자 안에서 생성자 호출이 가능 ex - this();
    →단, 맨 제일 선두에서만 가능함 - this(); public 안 - 제일 위에 배치

Test5. 생성자, 생성자 오버로딩하는 법

💻 입력


import java.util.Scanner;
import java.util.Set;

public class Test5 {

	private int x;
	
	//public Test5() {} 
	
	public void set(int x) {
		this.x = x;
	}

	public Test5() { // 생성자를 오버로딩할거면 기본생성자 생성해야함
		
		//this(200);//Test5(200)
		System.out.println("기본 생성자");
		
	}
	
	
	
	public Test5(int x) {
		
		this(); // 맨 처음 선두
		System.out.println("오버로딩된 생성자,,");
		this.x=x; // 값 초기화 됨
	System.out.println("x: "+this.x);
	
	}
	
	public void print() {
		System.out.println("X");
	}
	
	
	public static void main(String[] args) {

		Test5 ob1 = new Test5(); // 기본생성자로도 객체 생성(new)할거면 기본생성자 꺼내놔야함 
		ob1.set(20); // private 초기화 할 수 있는 방법 set 메서드 만들기 (this x=x;)
		ob1.print();
		
		Test5 ob2 = new Test5(100);
		ob2.print();
		
		Scanner sc = new Scanner(System.in);

		
	}

}

💡 **출력**
기본 생성자
X
기본 생성자
오버로딩된 생성자,,
x: 100
X


📌 Note Code


  • 생성자를 오버로딩하면 객체를 생성함과 동시에 값 초기화 됨 (값 필수!)

Test6. 사각형 각 길이, 넓이, 둘레를 구하여라

💻 입력


class RectA{
	
	private int w,h;
	
	public RectA() {//기본생성자
		
		
		
	}
	

	public RectA(int w,int h) { //오버로딩된 생성자
		this.w = w;
		this.h = h;
	}

	
	public void set(int w,int h) {
		this.w = w;
		this.h = h;
	}
	
	
	public int area() {
		return w*h;
	}
	
	
	public int length() {
		return (w+h)*2;
	}
	
	public void print(int a) {
		System.out.println("가로 : "+w);
		System.out.println("세로 : "+h);
		System.out.println("넓이 : "+a);
	}
	
	//메소드 오버로딩
	
	public void print(int a, int l) {
		System.out.println("가로 : "+w);
		System.out.println("세로 : "+h);
		System.out.println("넓이 : "+a);
		System.out.println("둘레 : "+l);
	}
	

	
}
public class Test6 {

	public static void main(String[] args) {

	RectA ob1 = new RectA();
	ob1.set(10, 20);
	int a = ob1.area();
	int l = ob1.length();
	ob1.print(a);
	ob1.print(a,l);
		
	System.out.println();	
	
	RectA ob2 = new RectA(100,200);//생성자 오버로딩시  객체생성함 동시에 값 초기화(값 필수!)
	a = ob2.area();//ob1.set(10, 20);이부분 삭제
	l = ob2.length();
	ob2.print(a);
	ob2.print(a,l);
	
	ob1.set(10, 20);
	
	System.out.println();	
	
	ob1.set(11, 22); //값을 중간에 바꿔야할 때는 메소드 필요!!!( ex, set() )
	a = ob2.area();//ob1.set(10, 20);이부분 삭제
	l = ob2.length();
	ob2.print(a);
	ob2.print(a,l);

	}

}

💡 **출력**
가로 : 10
세로 : 20
넓이 : 200
가로 : 10
세로 : 20
넓이 : 200
둘레 : 60

가로 : 100
세로 : 200
넓이 : 20000
가로 : 100
세로 : 200
넓이 : 20000
둘레 : 600

가로 : 100
세로 : 200
넓이 : 20000
가로 : 100
세로 : 200
넓이 : 20000
둘레 : 600



📌 Note Code


  • 상수변수 final :
    대문자
    ② 만드는 그 순간에 값 초기화 해야함
    ③ 프로그램이 종료될 때까지 이 값을 절대 바꿀 수 없음 ex)3.14

  • 초기화 블럭 : new를 만나서 자동으로 한번 실행되면 다시는 실행 x

  • ① static → ② 맨 위에서 new 엘베 타고 올라간 친구들 → ③ 생성자는 맨마지막


Test7. 생성자,static,초기화블럭

💻 입력

public class Test7 {

	int a = 5;
	
	{//초기화 블럭
		System.out.println("초기화 블럭a: "+a);
		a=10;                         
		System.out.println("초기화 블럭a: "+a);
	}
	
	static int b; //저장은 한번만!
	
	static {//static 블럭 - new를 만나지 않아도 메모리상에 올라감
		b = 10;
		System.out.println("static 블럭b: "+b);
	}
	
	
	//상수변수
	final int C; 

	//생성자가 제일 마지막에 실행됨
	public Test7() {//니가 날 초기화하지않으면 위 C에 에러뜬다!?
		System.out.println("생성자,,,");
		C = 100;
		System.out.println("C: "+C );
	}
	
	
	public static void main(String[] args) {

		Test7 ob1 = new Test7();
		
		Test7 ob2 = new Test7();
	}

}

💡 **출력**
static 블럭b: 10
초기화 블럭a: 5
초기화 블럭a: 10
생성자,,,
C: 100
초기화 블럭a: 5
초기화 블럭a: 10
생성자,,,
C: 100


📌 Note Code


  • Call By Value
    : stack 영역의 데이터가 heap영역으로 넘어감 (stack < heap)

  • Call By reference
    : heap 영역의 데이터는 stack영역으로 넘어갈 수 없는 대신, 주소를 주고받음

  • class의 초기값 = null


Test8. Call By Value / Call By Reference

💻 입력

import java.util.Calendar;

class Test{
	
	public int x = 10;
	
	public void sub(int a) {
		x+=a; // x=x+a;
	}
	
}


public class Test8 {

	public static void main(String[] args) {

		Test ob = new Test();
		
		//Call By Value
		int a = 20;
		
		System.out.println("sub()메소드 실행전 x: "+ob.x);
		ob.sub(a);
		System.out.println("sub()메소드 실행후 x: "+ob.x);
		
		//Call By Reference
		Test ob1;// class - Test의 초기값 = null
		ob1 = ob; // ob가 가지고있는 10번지 주소를 ob1에게 주소를 나눠줌
		
		System.out.println(ob.x);
		System.out.println(ob1.x);
		
		//Call By Reference
		//Calendar c1 = new Calendar(); x
		Calendar c1 = Calendar.getInstance();//11.24 - Static으로 만들게 되면 저장공간 1번만 
		Calendar c2 = Calendar.getInstance();//11.24
		Calendar c3 = Calendar.getInstance();//11.24
		Calendar c4 = Calendar.getInstance();//11.24
		Calendar c5 = Calendar.getInstance();//11.24
		
	}

}

💡 **출력**
sub()메소드 실행전 x: 10
sub()메소드 실행후 x: 30
30
30

0개의 댓글