본문 바로가기
Java

자바의 상속(캐스팅, 오버라이딩, 추상 클래스)

by 도리에몽 2022. 3. 7.

업캐스팅

서브 클래스의 객체에 대한 레퍼런스를 슈퍼 클래스 타입으로 변환하는 것

슈퍼 클래스의 레퍼런스로 서브 클래스의 객체를 가리킨다.

Person p;
Student s = new Student();
p = s; //업캐스팅

이때, 슈퍼 클래스 타입의 레퍼런스 p가 서브 클래스 객체(s)를 가리키도록 치환된다.

p는 Person 타입이기 때문에 Person 클래스의 멤버만 접근 가능하다. 즉, 업캐스팅한 레퍼런스로는 슈퍼 클래스의 멤버만 접근할 수 있다. 

 

업캐스팅은 명시접 타입 변환을 하지 않아도 된다.

p = (Person)s; //(Person)을 생략해도 됨

 

다운캐스팅

업캐스팅과 반대로 캐스팅하는 것이다. Person 타입의 레퍼런스를 Student 타입의 레퍼런스로 변환해 보자. 해당 결과로 인해 s를 통해서 Student 객체 전체를 접근할 수 있다.

다운캐스팅은 업캐스팅과 달리 명시적으로 타입 변환을 지정해야 한다.

Person p = new Student("이재문"); //업캐스팅
Student s = (Student)p; //다운 캐스팅, (Student)의 타입 변환 반드시 표시

 

업캐스팅과 instanceof 연산자

업캐스팅을 한 경우, 레퍼런스가 가리키는 객체의 진짜 클래스 타입을 구분하기 어렵다.

instanceof 연산자 사용

레퍼런스가 가리키는 객체가 어떤 클래스 타입인지 구분하기 위해, instanceof 연산자를 사용한다. 

레퍼런스 instanceof 클래스명

instanceof 연산자의 결과 값은 boolean 값으로,  '레퍼런스'가 가리키는 객체가 해당 '클래스' 타입의 객체이면 true이고 아니면 false로 계산한다.

instanceof는 객체에 대한 레퍼런스만 사용한다. 

if(3 instanceof int) //문법 오류
if("java" instanceof String) // true

 

메소드 오버라이딩

메소드 오버라이딩이란 슈퍼 클래스와 서브 클래스의 메소드 사이에 발생하는 관계로, 슈퍼 클래스에 선언된 메소드와 같은 이름, 같은 리턴 타입, 같은 매개 변수 리스트를 갖는 메소드를 서브 클래스에서 재작성하는 것이다.

'슈퍼 클래스 메소드 무시하기 혹은 덮어쓰기'로 표현할 수 있다. 메소드 오버라이딩은 동적 바인딩을 유발한다.

* 동적 바인딩: 슈퍼 클래스의 메소드를 무시하고 서브 클래스에서 오버라이딩된 메소드가 무조건 실행되도록 함

 

  • 메소드 오버라이딩의 제약 사항

1. 슈퍼 클래스의 메소드와 동일한 원형으로 작성한다.

슈퍼 클래스의 메소드와 동일한 이름, 매개변수 타입과 개수, 리턴 타입을 갖는 메소드 작성.

 

2. 슈퍼 클래스 메소드의 접근 지정자보다 접근 범위를 좁여 오버라이딩 할 수 없다.

접근 범위: public > protected > default > private

 

3. static이나 private 또는 final로 선언된 메소드는 서브 클래스에서 오버라이딩할 수 없다.

 

 

오버라이딩과 super 키워드

서브 클래스에서 super 키워드를 사용하면 정적 바인딩을 통해 슈퍼 클래스의 멤버에 접근할 수 있다. super는 슈퍼 클래스에 대한 레퍼런스이며, super를 이용해서 슈퍼 클래스의 필드와 메소드 접근이 가능하다.

super.슈퍼클래스의멤버

this와 super의 차이점

this와 super는 모두 레퍼런스로서 this는 현재 객체의 모든 멤버를, super는 현재 객체 내에 있는 슈퍼 클래스 멤버를 접근할 수 있다. this()는 생성자에서 다른 생성자를 호출할 때 사용하고, super()는 서브 클래스의 생성자에서 슈퍼 클래스의 생성자를 호출할 때 사용한다.

 

추상 메소드

추상 메소드란 선언은 되어 있으나 코드가 구현되어 있지 않은, 즉 껍데기만 있는 메소드이다. 추상 메소드를 작성하려면 abstract 키워드와 함께 원형만 선언하고 코드는 작성하지 않는다.

public abstract String getName();
publis abstract void setName(String s);

 

추상 클래스

추상 클래스는 상속에서 슈퍼 클래스로 사용되며, abstract 키워드로 선언해야 한다.

  • 추상 클래스가 되는 경우

1. 추상 메소드를 포함하는 클래스

abstract class Shape { //추상 클래스 선언
    public Shape() {}
    public void paint() { draw(); }
    abstract public draw(); //추상 메소드 선언
}

2. 추상 메소드가 없지만 abstract로 선언한 클래스

abstract class MyComponent {  //추상 클래스 선언
    String name;
    public void load(String name) {
    	this.name = name;
    }
}

오류 코드: 추상 메소드를 갖고 있지 않으면 반드시 추상 클래스로 선언되어야 한다.

class Fault {  //오류. 추상 클래스로 선언되지 않음
	abstract public void f();  //추상 메소드
}

 

  • 추상 클래스는 객체를 생성할 수 없다

추상 클래스는 객체를 생성할 목적으로 만든 클래스가 아니다. 추상 클래스에는 실행 코드가 없는 미완성 상태인 추상 메소드가 있을 수 있기 때문에, 추상 클래스의 객체를 생성하는 코드를 작성하면 컴파일 오류가 발생한다.

public class AbstractError {
	public static void main(String [] args) {
    	Shape shape; //추상 클래스의 레퍼런스 변수를 선언하는 것은 오류가 아님.
        shape = new Shape(); //컴파일 오류. 추상 클래스 Shape의 객체를 생성할 수 없다
    }
}

 

  • 추상 클래스의 상속

추상 클래스를 단순히 상속받는 서브 클래스는 추상 클래스가 된다. 추상 클래스의 추상 메소드를 그대로 상속받기 때문이다. 따라서 abstract를 붙여 추상 클래스임을 명시해야 컴파일 오류가 발생하지 않는다.

 

  • 추상 클래스의 구현과 목적

추상 클래스의 구현이란?

슈퍼 클래스에 선언된 모든 추상 메소드를 서브 클래스에서 오버라이딩하여 실행 가능한 코드로 구현하는 것

추상 클래스의 목적은?

추상 클래스는 추상 메소드를 통해 서브 클래스가 구현할 메소드를 명료하게 알려주는 인터페이스 역할을 하고, 서브 클래스는 추상 메소드를 목적에 맞게 구현하는 다형성을 실현할 수 있다.

//Calculator.java
abstract class Calculator {
	public abstract int add(int a, int b); //두 정수의 합 리턴
	public abstract int subtract(int a, int b); //두 정수의 차 리턴
	public abstract double average(int[] a); //배열에 저장된 정수의 평균 리턴
}
//GoodCalc.java
public class GoodCalc extends Calculator {
	@Override
	public int add(int a, int b) {
		return a + b;
	}
	@Override
	public int subtract(int a, int b) {
		return a - b;
	}@Override
	public double average(int[] a) {
		double sum = 0;
		for(int i = 0; i < a.length; i++) {
			sum += a[i];
		}
		return sum / a.length;
	}
	
	public static void main(String[] args) {
		GoodCalc c = new GoodCalc();
		System.out.println(c.add(2, 3));
		System.out.println(c.subtract(2, 3));
		System.out.println(c.average(new int [] {2, 3, 4}));

	}

}

 

'Java' 카테고리의 다른 글

자바의 상속(인터페이스)  (0) 2022.03.07