다형성, 추상화

seongmin·2022년 9월 9일
0

Java

목록 보기
6/30
post-thumbnail

다형성

  • 다형성은 한 타입의 참조변수를 통해 여러 타입의 객체를 참조할 수 있도록 만든 것을 의미한다.
    -> 상위 클래스 타입의 참조변수를 통해서 하위 클래스의 객체를 참조할 수 있도록 허용한 것

  • GirlFriend 를 참조변수의 타입으로 지정해주어야 하지만, 그러지 않고 상위 클래스 Friend 를 타입으로 지정해주고 있다. 상위 클래스 타입의 참조변수로 하위 클래스의 객체를 참조하는 것을 보여주는 예시임.

  • 상위 클래스인 Friend 타입으로 하위 클래스 GirlFriend 를 참조하는 것은 가능하지만, 그 반대로 하위 클래스 GirlFriend 의 타입으로 상위 클래스 객체 Friend 를 참조하는 것은 불가능하다.

그 이유는 실제 객체인 Friend 의 멤버 개수보다 참조변수 friend1 이 사용할 수 있는 멤버 개수가 더 많기 때문이다.

타입 변환

  • 참조 변수의 타입 변환은 사용할 수 있는 멤버의 개수를 조절하는 것을 의미하며, 사용하기 위해서는 다음과 같은 세 가지 조건을 충족해야 한다.
  1. 서로 상속관계에 있는 상위 클래스 - 하위 클래스 사이에만 타입 변환이 가능하다.
  2. 하위 클래스 타입에서 상위 클래스 타입으로의 타입 변환(업캐스팅)은 형변환 연산자(괄호)를 생략할 수 있다.
  3. 반대로 상위 클래스에서 하위 클래스 타입으로 변환(다운캐스팅)은 형변환 연산자(괄호)를 반드시 명시해야한다.

instanceof 연산자

  • instanceof 연산자는 참조변수의 타입 변환, 즉 캐스팅이 가능한 지 여부를 oolean타입으로 확인할 수 있는 자바의 문법요소.
참조_변수 instanceof 타입
  • 참조_변수 instanceof 타입 입력했을 때 리턴 값이 true가 나오면 참조 변수가 검사한 타입으로 타입 변환이 가능하며, 반대로 false가 나오는 경우에는 타입 변환이 불가능하다. 만약에 참조 변수가 null인 경우에는 false를 반환한다.

추상화

  • 추상화의 핵심적인 개념은 공통성과 본질을 모아 추출하는 것을 의미함. 추상화와는 반대로 기존 클래스들의 공통적인 요소들을 뽑아서 상위 클래스를 만들어 내는 것이라고 할 수 있다.

  • 공통적인 속성과 기능을 모아서 정의해주면 코드의 중복을 줄일 수 있고, 보다 효과적으로 클래스 간의 관계를 설정할 수 있으며, 유지/보수가 용이해진다.

abstract 제어자

  • 자바에서 abstract라는 단어가 내포하는 의미는 ‘미완성'이라고 할 수 있다.

  • abstract 는 주로 클래스와 메서드를 형용하는 키워드로 사용되는데, 메서드 앞에 붙은 경우를 ‘추상 메서드(abstract method)’, 클래스 앞에 붙은 경우를 ‘추상 클래스(abstract class)’라 부른다.

  • 어떤 클래스에 추상 메서드가 포함되어있는 경우 해당 클래스는 자동으로 추상 클래스가 된다.

abstract class AbstractExample { // 추상 메서드가 최소 하나 이상 포함돼있는 추상 클래스
	abstract void start(); // 메서드 바디가 없는 추상메서드
}

추상 클래스

  • 메서드 시그니처만 존재하고 바디가 선언되어있지 않은 추상 메서드를 포함하는 ‘미완성 설계도’이다. 추상 클래스는 미완성 설계도이기 때문에 메서드 바디가 완성이 되기 전까지 이를 기반으로 객체 생성이 불가하다.

추상 클래스를 만드는 이유 ?

  1. 추상 클래스는 상속 관계에 있어 새로운 클래스를 작성하는데 매우 유용함.
    -> 추상 클래스를 사용하면 상속을 받는 하위 클래스에서 오버라이딩을 통해 각각 상황에 맞는 메서드 구현이 가능하다는 장점이 있다.

  2. 추상 클래스는 자바 객체지향 프로그래밍의 마지막 기둥인 추상화를 구현하는데 핵심적인 역할을 수행함.
    -> 만약 여러 사람이 함께 개발하는 경우, 공통된 속성과 기능임에도 불구하고 각각 다른 변수와 메서드로 정의되는 경우 발생할 수 있는 오류를 미연에 방지할 수 있다.

final 키워드

  • final 키워드는 그 위치에 따라 의미가 달라진다.
위치의미
클래스변경 또는 확장 불가능한 클래스, 상속 불가
메서드오버라이딩 불가
변수값 변경이 불가능한 상수
final class FinalEx { // 확장/상속 불가능한 클래스
	final int x = 1; // 변경되지 않는 상수

	final int getNum() { // 오버라이딩 불가한 메서드
		final int localVar = x; // 상수
		return x;
	}
}
  • 각각의 클래스, 메서드, 그리고 변수 앞에 final 제어자가 추가되면 이제 해당 대상은 더이상 변경이 불가하거나 확장되지 않는 성질을 지니게 된다.

인터페이스

  • 인터페이스는 기본적으로 추상 메서드와 상수만을 멤버로 가질 수 있다는 점에서 추상 클래스에 비해 추상화 정도가 더 높다고 할 수 있다.

  • 일반 클래스와 다르게, 내부의 모든 필드가 ublic static final로 정의되고, staticdefault 메서드 이외의 모든 메서드가 public abstract 로 정의된다는 차이가 존재한다. 모든 인터페이스의 필드와 메서드에는 위의 요소가 내포되어있기 때문에 명시하지 않아도 생략이 가능하다.

public interface InterfaceEx {
    public static final int rock =  1; // 인터페이스 인스턴스 변수 정의
    final int scissors = 2; // public static 생략
    static int paper = 3; // public & final 생략

    public abstract String getPlayingNum();
		void call() //public abstract 생략 
}
  • 추상클래스와 마찬가지로 인터페이스도 그 자체로 인스턴스를 생성할 수 없고, 메서드 바디를 정의하는 클래스를 따로 작성해야한다. implements 키워드를 사용한다.
class 클래스명 implements 인터페이스명 {
		... // 인터페이스에 정의된 모든 추상메서드 구현
}
  • 특정 인터페이스를 구현한 클래스는 해당 인터페이스에 정의된 모든 추상메서드를 구현해야만 한다.

어떤 클래스가 어떤 인터페이스를 구현한다는 것은 그 인터페이스가 가진 모든 추상 메서드들을 해당 클래스 내에서 오버라이딩하여 바디를 완성한다라는 의미를 가진다.

다중 구현

  • 인터페이스는 다중적 구현이 가능하다. 하나의 클래스가 여러 개의 인터페이스를 구현할 수 있다. 다만 인터페이스는 인터페이스로부터만 상속이 가능하고, 클래스와 달리 Object 클래스 와 같은 최고 조상이 존재하지 않는다.
class ExampleClass implements ExampleInterface1, ExampleInterface2, ExampleInterface3 { 
				... 생략 ...
}
  • 클래스에서 다중 상속이 불가능했었던 핵심적인 이유는 만약 부모 클래스에 동일한 이름의 필드 또는 메서드가 존재하는 경우 충돌이 발생하기 때문이다. 반면 인터페이스는 애초에 미완성된 멤버를 가지고 있기 때문에 충돌이 발생할 여지가 없기 때문에 안전하게 다중 구현이 가능하다.

  • 특정 클래스는 다른 클래스로부터의 상속을 받으면서 동시에 인터페이스를 구현할 수 있다.

추상 클래스와 인터페이스의 차이

  • 인터페이스도 추상 클래스처럼 자바에서 추상화를 구현하는 데 활용된다는 점에서 동일하지만, 추상클래스에 비해 더 높은 추상성을 가진다는 점에서 큰 차이가 있다.

  • 추상 클래스를 설계가 모두 끝나지 않은 “미완성 설계도" 에 비유할 수 있다면, 인터페이스는 그보다 더 높은 추상성을 가지는 가장 기초적인 “밑그림" 에 빗대어 표현할 수 있다.

  • 추상 클래스는 메서드 바디가 없는 추상 메서드를 하나 이상 포함한다는 점 외에는 기본적으로 일반 클래스와 동일하다고 할 수 있다.

  • 반면 인터페이스는 기본적으로 추상 메서드와 상수만을 멤버로 가질 수 있다는 점에서 추상 클래스에 비해 추상화 정도가 더 높다고 할 수 있다.

0개의 댓글