멋사 부트캠프/Java 프로그래밍

03. 객체 생성, 상속&다형성 [Overload / Override]

cTosMaster 2025. 3. 5. 22:17

1. 객체 생성 및 메모리 할당

 

생성자 → new b_exam();

객체 인스턴스 주소값 → m 저장 (객체 인스턴스가 변수 m에 binding 되었다고 표현한다.)

클래스 내부에 static으로 정의되지 않은 메서드 → 인스턴스 메서드, 변수는? 인스턴스 변수

 

2. Wrapper 클래스란?

   기본 데이터 타입(primitive type)을 객체로 다루기 위해 제공되는 클래스

    ex) Integer, Double, Number…

    

   *) 왜 이걸 쓸까?

  기본 타입은 객체가 아니기 때문에 컬렉션(List, Set, Map 등)에 저장할 수 없어.

  대신, Wrapper 클래스를 사용하면 기본 타입을 객체로 변환해서 저장할 수 있음.

  

  Boxing : 기본타입 -> 객체

int num = 10;   // 기본 타입
Integer obj = Integer.valueOf(num);  // int → Integer (Boxing)

 

  UNBoxing : 객체 -> 기본타입

Integer obj = Integer.valueOf(20);  // Integer 객체 생성
int num = obj.intValue();  // Integer → int (Unboxing)

 

🔹 Wrapper 클래스 주요 메서드

       

문자열을 숫자로 변환

int num = Integer.parseInt("100");  // 문자열 → int 변환
double d = Double.parseDouble("3.14");  // 문자열 → double 변환

       

숫자를 문자열로 변환

String str = Integer.toString(100);  // int → 문자열 변환
String str2 = Double.toString(3.14); // double → 문자열 변환

     

최댓값/최솟값 상수

System.out.println(Integer.MAX_VALUE); // 2147483647
System.out.println(Integer.MIN_VALUE); // -2147483648

 

3. 상속

기능확장, 상속관계는 외부에서 봤을 때 하나의 클래스처럼 간주한다.

상속에 관한 부분은 "Override"와 연관이 깊다.

상속(inheritance)은 객체지향 프로그래밍의 핵심 개념 중 하나로,

기존 클래스의 속성(field)과 메서드를 새로운 클래스가 물려받는 것을 의미합니다.

final 클래스 -> 더 이상 상속될 수 없는 클래스

 클래스 단일 상속, 부모는 자식을 모른다, 인터페이스-클래스 간에는 다중 상속 가능

 

* 상속 시, 부모 클래스 타입에 자식 클래스 타입을 대입하여도 문제가 없다.

  (이후의 정적/동적 바인딩에서 자세히 다룬다.)

 

 

🔹 Full 캡슐화란?

선언된 모든 멤버변수는 은닉하고 오픈된 메소드를 통해 값 전달 및 변경하고

리턴하는 구조 (private, public 활용)

전달 및 변경(setter), 리턴하는 구조(getter)를 가진다.

 

🔹Override

상속 시, 부모 클래스의 메서드를 자식 클래스에서 {메서드명, 매개변수, 반환 타입을 동일}

재정의 하는 것. [다른 상위 클래스 → 현재 클래스]

class MyAddress{
	//멤버 변수 은닉화
	private String name;
	private String addr;
	private String tel;
	
	//멤버 메서드 Name Se/Ge
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	//멤버 메서드 Addr Se/Ge
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public String getAddr() {
		return addr;
	}
	//멤버 메서드 Tel Se/Ge
	public void setTel(String tel) {
		this.tel = tel;
	}
	public String getTel() {
		return tel;
	}	
}
public class MTest01 {

	public static void main(String[] args) {
		MyAddress a1 = new MyAddress();
		MyAddress b1 = new MyAddress();
		MyAddress c1 = new MyAddress();
		
		a1.setName("홍길동"); a1.setAddr("서울"); a1.setTel("02-000-0000");
		b1.setName("임꺽정"); b1.setAddr("부산"); b1.setTel("051-000-0000");
		c1.setName("강동원"); c1.setAddr("인천"); c1.setTel("031-000-0000");
	
		System.out.println("이름 : " + a1.getName() + "\t 주소 : " + a1.getAddr() + "\t H.P : " + a1.getTel());
		System.out.println("이름 : " + b1.getName() + "\t 주소 : " + b1.getAddr() + "\t H.P : " + b1.getTel());
		System.out.printf("이름 : %5s 주소 : %5s H.P : %15s \n", c1.getName(), c1.getAddr(), c1.getTel());
		
		//홍길동을 이길동으로 변경 후 a1을 출력해보자.
		System.out.println("Q1. 홍길동을  이길동으로 변경후 a1을 출력해보자.  ");
		a1.setName("이길동");
		System.out.println(a1.getName());
		
        System.out.println("Q2. 인천을 제주도로 변경후 정길동과 인천만 출력해보자.   ");
        c1.setAddr("제주도"); b1.setName("정길동");
        System.out.printf("%10s %10s \n", a1.getName(), c1.getAddr());
		
        System.out.println("Q3. 부산을 대구로 변경 후 이름과 대구를 출력해보자.   ");
        b1.setAddr("대구");
		System.out.printf("%10s %10s \n", b1.getName(), b1.getAddr());
		
        System.out.println("Q4. 최길동의 전화번호를  000으로 변경후 전체 c1의 레코드를 출력해보자   ");
        c1.setName("최길동"); a1.setTel("000");
		System.out.printf("%10s %10s %10s \n", a1.getName(), a1.getAddr(), a1.getTel());
		
        System.out.println("Q5. 레코드의 3명의 이름만 출력 해보자.    ");
        System.out.println(a1.getName() + b1.getName() + c1.getName());
		
	}
}

 

🔹생성자

    - 클래스 이름과 동일하되 반환형은 없다.

    - 오버로드 할 수 있다.

    - 생성자는 객체를 생성할 때, 단 한번만 호출된다. new className();

    - 메서드처럼 명시호출 할 수 없다.

    - 생성자는 상속되지 않으며 객체를 생성할 때 단 한번 호출된다.

    - 생성자를 명시하지 않으면 기본 생성자가 호출되고 명시하면 명시된 생성자가 호출된다.

    - 생성자는 멤버변수 초기화를 목적으로 한다.

    - 자바는 소멸자는 따로 없으며, GC가 알아서 처리한다.

 

4. 다형성

하나의 인터페이스로 여러 개의 타입을 사용할 수 있는 성질

같은 이름의 메서드나 객체가 여러 형태로 동작할 수 있는 것을 의미함.

 

🔹Overload

class MathUtils {
    // int를 받는 sum()
    int sum(int a, int b) {
        return a + b;
    }

    // double을 받는 sum()
    double sum(double a, double b) {
        return a + b;
    }
}

public class Main {
    public static void main(String[] args) {
        MathUtils mu = new MathUtils();
        System.out.println(mu.sum(3, 5));    // int sum() 호출
        System.out.println(mu.sum(3.5, 2.5)); // double sum() 호출
    }
}

>> 같은 이름의 메서드를 매개 변수, 자료형을 다르게 하여 선택 동작 하게 하는 것.