[Java] Class, Inheritance

Jay Mild Lee·2022년 11월 23일
0

Java

목록 보기
6/10
post-thumbnail

I. Class

1. Constructor overloading(생성자 오버로딩)

외부에서 제공되는 다양한 데이터들을 이용해 객체를 초기화하기 위해서는 생성자도 다양화될 필요가 있다. Java는 다양한 방법으로 객체를 생성할 수 있도록 지원하는데, 이를 생성자 오버로딩이라고 한다.

1) 예시

아래는 field가 주어지는 여부에 따라 구분된 생성자들이다.

public class Car {
    // field
    String company;
    String model;
    String color;
    int maxSpeed;
    int speed;

    // constructor, Overloading
    Car() {

    }
    Car(String company) {
        this.company = company;
    }
    Car(String company, String model) {
        this.company = company;
        this.model = model;
    }
    Car(String company, String model, String color) {
        this.company = company;
        this.model = model;
        this.color = color;
    }
    Car(String company, String model, String color, int maxSpeed) {
        this.company = company;
        this.model = model;
        this.color = color;
        this.maxSpeed = maxSpeed;
    }
}

2) 다른 생성자 호출 : this()

생성자 오버로딩이 많아질 경우, 생성자 간의 중복된 코드가 발생하게 된다. this() 메소드는 Class의 다른 생성자를 호출함으로써, 중복된 코드를 간결하게 개선할 수 있다.

public class Car {
    // field
    String company;
    String model;
    String color;
    int maxSpeed;
    int speed;

    // constructor, Overloading
    // constructor #1
    Car() {
        this("현대자동차", "그랜저", "회색", 250); 	// 2번 생성자 호출
    }
    
    // constructor #2
    Car(String company) {
        this(company, "그랜저", "회색", 250);		// 3번 생성자 호출
    }
    
    // constructor #3
    Car(String company, String model) {
        this(company, model, "회색", 250);		// 4번 생성자 호출
    }
    
    // constructor #4
    Car(String company, String model, String color) {
        this(company, model, color, 250);		// 5번 생성자 호출
    }
    
    // constructor #5
    Car(String company, String model, String color, int maxSpeed) {
        this.company = company;
        this.model = model;
        this.color = color;
        this.maxSpeed = maxSpeed;
    }
}

2. method의 매개 변수를 모를 경우

일반적으로 메소드의 매개 변수는 그 숫자가 정해져있다. 하지만 특정 상황에서는 메소드의 매개 변수의 수를 알 수 없는 경우도 있다. 예를 들어, 여러 원소를 합산하는 메소드를 선언해야 한다면 몇 개의 변수가 입력될 지 알 수 없다. 이럴 땐, 매개 변수를 배열 타입으로 선언함으로써 해결할 수 있다.

int sum(int[] values){
	int result = 0;
    for (int i = 0; i < values.length ; i++){
    	result += values[i];
    }
    return result;
}

2. Method Overloading(메소드 오버로딩)

클래스 내에 같은 이름을 가진 메소드를 여러 개 선언하는 것. 메소드 오버로딩은 매개 변수의 ✔타입, ✔개수, ✔순서 중 하나가 달라져야 한다.

예를 들어 다음과 같은 메소드가 있다고 가정하자.

int plus(int x, int y){
	int result = x + y;
	return result;
}

동일한 로직으로 double의 값을 계산하고 리턴하는 메소드가 필요한 경우 굳이 다른 메소드를 선언할 필요 없이, 같은 이름으로 리턴 타입과 변수 타입만 변경해주면 된다.

double plus(double x, double y){
	double result = x + y;
	return result;
}

오버로딩된 메소드들은 JVM에 의해서 변수 값의 타입을 보고 적용된다.

1) JVM의 위대함(?)

위의 plus() 메소드를 다음과 같이 호출하여 사용한다고 가정하자.

int x = 10;
double y = 15.3;
plus(x, y)

int와 double로 매개 변수가 실행되기 때문에 컴파일 에러가 날 것 같지만, 위대한 JVM은 매개 변수의 타입 변환을 통해 오버로딩된 메소드들 중 적용 가능한 메소드가 있는지 검사한다.
때문에 위의 코드는 x를 double로 타입변환을 하고, 이후 double plus() 메소드가 적용된다.

II. Inheritance(상속)

1. Class Inheritance

Class 선언 시, 중복되는 코드를 줄이고 유지보수를 간편하게 하기 위해 상속을 선언할 수 있다. 선언 방법은 다음과 같다.

class [자식 Class] extends [부모 Class]{
	// field
    // constructor
    // method
}

1) 부모의 생성자 호출

1-1) 부모의 기본 생성자 호출

public [자식 Class]() {
	super();
}

1-2) 부모의 기본 생성자가 없는 경우

public class People {
	public String name;
    public String ssn;
    
    public People(String name, String ssn){
    	this.name = name;
        this.ssn = ssn;
    }
}        

위 People 클래스의 경우, 기본 생성자 없이 변수 2개(name, ssn)를 받아 생성된다. 이런 경우 People을 상속하는 클래스는 동일하게 2개의 변수(name, ssn)를 받을 수 있도록 구성해야 한다. 그 예시는 다음과 같다.

public class Student {
	public int studentNum;

    public Student(String name, String ssn, int studentNum){
    	this.name = name;
        this.ssn = ssn;
        this.studentNum = studentNum;
    }
}        

2) Method Overriding (메소드 오버라이딩)

상속받은 메소드가 자식 클래스에서 사용하기 힘든 상황이 있을 수 있다. Java는 이런 경우 메소드를 자식 클래스 내에서 간단하게 변경할 수 있는 기능을 제공한다.

2-1) Method Overriding의 규칙

  • 부모의 메소드와 동일한 시그니쳐(✔리턴 타입, ✔메소드 이름, ✔매개 변수 목록)를 가져야 한다.
  • 접근 제한을 더 강하게 정의할 수 없다.
  • 새로운 예외(Exception)을 throws 할 수 없다.

2-2) 예시

public class Calculator {
	double area Circle(double r){
    	return 3.14159 * r * r;
    }
}
public class Precise_Calculator extends Calculator{
	@Override
	double area Circle(double r){
    	return MATH.PI * r * r; 	//Math API 사용
    }
}

@Override : 컴파일러가 해당 메소드가 정확히 재정의된 것인지 확인

2-3) 부모 메소드 호출

자식 클래스의 내부에서 재정의된 부모 클래스의 메소드를 호출해야 하는 상황이 발생할 수도 있다. 이 때, super 키워드를 이용해 부모 메소드를 호출할 수 있다.

super.[메소드 이름]()		// 부모 메소드 호출

0개의 댓글