Java

다형성_추상클래스 / 인터페이스 정리

coolcode 2022. 11. 23. 20:40

다형성 : 하나의 객체가 여러가지 타입을 가질 수 있는 것

부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있음

* 참조변수의 다형성 : 참조변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스 멤버 개수보다 같거나 적어야 참조 가능

 

부모 -> 자식 참조 가능 / 자식 -> 부모 참조 불가 

이유는 자식 타입의 참조 변수가 사용할 수 있는 멤버 개수 > 실제 인스턴스(부모타입)의 멤버 개수보다 많기 때문

자식 클래스에서 사용할 수 있는 멤버의 개수는 언제나 부모 클래스와 같거나 많음(상속을 통해 확장되기 때문)

 

참조변수 타입변환 

서로 상속 관계에 있는 클래스 사이에만 타입변환 가능

자식 클래스 타입에서 부모 클래스 타입으로의 변환은 생략 가능 (부모 -> 자식 타입 변환은 반드시 명시해야 함)

 

instanceof 연산자 (참조변수 instanceof 클래스 이름)

다형성으로 인해 런타임시 참조변수가 실제로 참조하고 있는 인스턴스 타입을 확인할 필요가 있음

해당 연산자는 참조변수가 참조하고 있는 인스턴스의 실제 타입을 확인해줌

public class Study {

    static class Parent{

    }

    static class Child extends Parent{

    }

    static class Familly extends Parent{

    }

    Parent parent = new Child();
    Child child = (Child) new Parent();

    public static void main(String[] args) {
        Parent parent = new Parent();
        System.out.println(parent instanceof Child); // false
        System.out.println(parent instanceof Parent); // true

        Parent parent = new Child();
        System.out.println(parent instanceof Child); // true
		System.out.println(parent instanceof Parent); // true (Child는 Parent를 참고하고 있기 때문)

    }
}

 

추상메서드 abstract method

자식클래스에서 반드시 오버라이딩 해야 하는 메서드

자바에서 추상 메서드를 선언하여 사용하는 목적은 추상 메서드가 포함된 클래스를 상속받는 자식 클래스가 반드시 해당 메서드를 구현하도록 하기 위함

모듈처럼 중복되는 부분이나 공통적인 부분만을 재정의하여 사용하게 함으로써 생산성이 향상됨

추상메서드는 선언부만 존재하며 구현부는 상속받는 자식 클래스에서 오버라이딩하여 재정의 후 사용함

abstract 반환타입 메서드명();
> abstract void sampleMethod();
> 이렇게 선언부만 있고 구현부 없이 세미콜론으로 마침

 

추상클래스 abstract class

하나 이상의 추상 메서드를 포함하는 클래스를 가르킴 (이 특징을 제외하면 일반 클래스와 같음)

추상클래스는 다형성을 가지는 메서드의 집합을 정의할 수 있도록 해줌

즉, 반드시 사용되어야 하는 메서드를 추상클래스에 추상 메서드로 선언해 놓으면 이 클래스를 상속받는 모든 자식 클래스에서는 추상 메서드를 반드시 재정의 해야 함

abstract class Parent {
	abstract void sampleMethod();
}

class Child extends Parent {
	@Override // 오버라이딩 하지 않으면 오류 
    void sampleMethod(){
    	// 재정의
    }
}

 

추상클래스는 동작이 정의되지 않은 추상메서드를 포함하고 있기 때문에 인스턴스를 생성할 수 없고

추상 클래스는 상속을 통해 자식클래스를 만들고 자식클래스에서 모든 추상 메서드를 오버라이딩 하고 난 후

자식클래스의 인스턴스로 생성할 수 있음 (추상 메서드 오버라이딩 하지 않으면 자식 클래스의 인스턴스도 생성 불가함)

 

인터페이스 interface

자바에서는 클래스의 다중 상속을 지원하지 않기 때문에 인터페이스를 통한 다중 상속을 구현할 수 있음

인터페이스는 다른 클래스를 작성시 기본 틀을 제공하며 클래스 간의 매개역할을 하는 일종의 추상클래스를 의미함

추상클래스는 추상메서드를 포함할 수 있다는 특징 외에 일반 클래스와 동일하게 생성자, 필드, 일반 메서드 포함 가능

반면 인터페이스는 오로지 추상 메서드와 상수만을 포함 할 수 있음

public interface Study {
	// 인터페이스의 모든 필드는 반드시 public static final 이어야 함
    public static final int Number = 1;
    abstract public void sampleMethod(String str1,String str2);
    
    // 인터페이스 내에서 일반 메서드 선언시 'Interface abstract methods cannot have body' 오류 메세지
    // 인터페이스의 모든 메서드는 public abstract 이어야 함
    public void sampleMethod2(){
    };
    
    > 접근제어자는 생략 가능 / 컴파일 시 컴파일러가 자동으로 추가해줌
}

 

인터페이스 구현

추상클래스와 마찬가지로 인스턴스 직접 생성은 불가함 

구현 클래스를 작성하고 인터페이스를 implemnets + 인터페이스의 추상 메서드 오버라이딩 해야 함

public interface Study {
    static final int Number = 1;
    abstract  void sampleMethod(String str1,String str2);
}

class Student implements Study{
    @Override
    public void sampleMethod(String str1, String str2) {
        
    }
}

> 만일 모든 추상 메서드를 구현하지 않는다면 abstract 키워드를 사용하여 추상클래스로 선언해야함

인터페이스는 인터페이스로부터만  상속 받을 수 있고 여러 인터페이스를 동시에 상속 받을 수 있음

interface Animal extends Study,Math {}

interface Math {}

class Tests implements Animal, Study {
    @Override
    public void sampleMethod(String str1, String str2) {
    }
}

 

인터페이스의 장점

- 다중 상속이 가능함

- 대규모 프로젝트 개발 시 일관되고 정형화된 개발 표준화 

- 클래스의 작성과 인터페이스의 구현을 동시에 진행할 수 있어 개발 시간 단축 

- 클래스간의 관계를 인터페이스로 연결하면 클래스마다의 독립적 프로그래밍이 가능함

 

* 참고

익명클래스

익명 클래스는 매우 제한적인 용도에 사용되며, 구현해야 하는 메소드가 매우 적은 클래스를 구현할 때 사용됨

// 선언과 동시에 생성하여 참조변수에 대입함

클래스이름 참조변수이름 = new 클래스이름(){

    // 메소드 선언

};