[Java] 객체지향 (JVM구조, 오버로딩, 생성자, this.)

         JVM의 메모리구조     

    메서드 영역(method area)

    • 프로그램 실행 중에 어떤 클래스가 사용되면 해당 클래스에 대한 정보(클래스데이터)를 저장.
    • 이 때 그 클래스의 클래스 변수도 함께 생성

    힙 영역(heap)

    • 인스턴스가 생성되는 공간. 인스턴스 변수들도 생성.

    호출 스택(call stack)

    • 메서드 작업에 필요한 메모리가 제공되는 공간.
    • 메서드가 호출되면 호출스택에 메모리를 할당하고, 종료되면 해제한다.
    • 맨 위의 메서드 하나만 실행되고, 나머지는 대기한다.

     


         오버로딩     

    • 보통 하나의 메서드 이름에 하나의 메서드를 싣는데 오버로딩은 한 클래스 안에 같은 이름의 메서드를 여러개 정의하는 것.
    • 대표적인 예로 prinln() 메서드가 있다.
    • 오버로딩의 조건
      • 메서드 이름이 같을 것.
      • 매개변수의 개수, 타입, 또는 순서 중 하나가 달라야 한다. (반환타입은 영향❌)
        컴파일러는 매개값 타입을 가지고 메서드를 찾기 때문에 매개변수가 동일하다면 오버로딩❌
        메서드의 이름과 매개변수가 같고 반환타입만 다르다면 오버로딩❌
    class MethodOverloading{
    	public int add(int x , int y) {
    		return x + y;
    	}
    	public int add(int x , int y, int z) {
    		return x + y + z;
    	} 
    	public double add(double dx , int y) {
    		return dx + y;
    	}
    	public double add(int x, double dx) {
    		return x + dx;
    	}
    	public double add(double dx, double dy) {
    		return dx + dy;
    	}
    }
    public class MethodOverloadingExam {
    	public static void main(String[] args) {
    	
    	MethodOverloading mo = new MethodOverloading();
    
    	System.out.println("int x + int y : "+mo.add(10, 15));
    	System.out.println("int x + int y + int z : " +mo.add(10, 15, 7));
    	System.out.println("double dx + int y : " + mo.add(13.5, 15));
    	}
    }

    🤔 코드 순서가 println 메서드가 먼저 와도 출력 순서는 add메서드가 먼저 출력된다. 왜일까?

    → println메서드가 결과를 출력하기 위해선 add메서드가 먼저 계산되어야 하기 때문이다!

    🤔 add(int x , int y)줄이 없다고 할 때 add(10, 15)를 호출하면 < The method add(double, int) is ambiguous for the type ~ >에러가 뜸 왜일까?

    → add(double dx , int y)를 호출한 건지 add(int x, double dx)를 호출한 건지 알 수가 없기 때문

     


     

         생성자     

    • 인스턴스가 생성될 떄마다 호출되는 ‘인스턴스 초기화 메서드
      • 인스턴스 생성시 수행할 작업(초기화)에 사용
    • 메서드와 같이 클래스 내에 선언되지만 생성자는 리턴값이 없다.(void❌)
    • 생성자를 실행시키지 않고는 클래스로부터 객체를 만들 수 없다.
    • 모든 클래스는 생성자가 반드시 존재해야 하고, 하나 이상 가질 수 있다.
      • 생성자가 없으면 컴파일러가 기본 생성자를 자동으로 추가한다. 생성자가 1개라도 있으면 자동 추가
    //기본생성자(매개변수가 없는 생성자)
    클래스명(){}
    
    //생성자 선언(매개변수가 있는 생성자)
    클래스명(매개변수 선언, ...){     //매개변수는 new연산자로 생성자를 호출할 때 외부의 값을
    		인스턴스 초기화 코드 작성     //생성자 블록 내부로 전달하는 역할
    }

    • 매개변수가 다른 생성자를 여러개 선언하는 것.

    2. 생성자 this()

    • 생성자에서 같은 클래스 안의 다른 생성자를 호출할 때 사용한다.
    • 다른 생성자 호출할 땐 반드시 생성자의 첫 줄에서만 사용
    • 오버로딩이 많아지면 생성자 간의 중복 코드가 발생할 수 있다
      • 따라서 필드 초기화 내용은 한 생성자에만 집중적으로 작성하고
        나머지 생성자는 초기화 내용을 가진 생성자를 호출하는 것이다.(중복제거)
    public class Car {
    	String company, color;
    	int speed;
    	
    	Car(){
    		//Car("기아", "노랑", 250);
    		this("기아", "노랑", 250);	//this()로 다른 생성자 호출 
    	}
    	Car(String company){
    		this(company, "블랙", 300);	//this()로 다른 생성자 호출
    	}
    	Car(String company, String color, int speed){    //호출되는 생성자
    		this.company = company;
    		this.color = color;
    		this.speed = speed;
    	}}

     

    3. 참조변수 this (생성자 this와 관계❌)

    • 객체 자신을 가리키는 참조변수 → 객체 자신의 주소가 저장되어 있다.
    • 인스턴스 메서드와 생성자에서 사용가능하다. → 지역변수로 숨겨진 채로 존재한다? 선언 안해도 사용가능
    • static 메서드에서 사용불가
    • 주로 지역변수(lv)와 인스턴스변수(iv)를 구별할 때 사용한다.
      (생성자와 메서드의 매개변수 이름이 필드와 동일한 경우)

    💡 this.company등 this가 없으면 모두 lv로 간주한다.(가까운쪽) 따라서 this.가 있어야 iv로 간주함( 참조변수 .변수이름)

     

    댓글