TIL(Today I Learned)

추상화(Abstract)

keepgoing 2022. 9. 28. 18:23

추상화란?
추상화(Abstract)란 클래스들의 중요하고 공통된 성질들을 추출하여 슈퍼클래스로 만든 것입니다.

 

추상화의 원칙
추상화 방식으로 메서드를 만들 땐 메서드의 기능을 쉽고 분명하게 이해할 수 있는 메서드명을 짓습니다.
하나의 메서드는 완전한 하나의 기능만을 갖습니다.
메서드의 코드 길이를 최대한 짧고 간결하게 작성합니다.

 

추상화 사용 이유
추상화를 사용했을 시 다음과 같은 장점이 있습니다.
- 코드의 가독성, 간결성, 유지보수성(코드를 짧고 간결하게 작성하고, 추상화 클래스로 메서드를 관리하기 때문)
- 코드의 재사용성(같은 기능을 하는 메소드를 여러 클래스에서 사용할 수 있기 때문)
- 중복코드 감소(여러 클래스에서 공통으로 사용되는 메서드를 슈퍼클래스에 작성하고 하위 클래스에선 가져와 사용만 하면 되기 때문)

 

추상화 예제 코드

package abstractEx;

public class Main {
	public static void main(String[] args) {
		Animal animal = new Animal(new Cat());

		animal.input("콩순이다",26);
	}
}

package abstractEx;

public class Animal {
	AnimalType animalType;
	
	public Animal(AnimalType animalType) {
		this.animalType = animalType;
	}
	
	public void input(String name, int age) {
		animalType.input(name, age);
	}
}

package abstractEx;

public abstract class AnimalType {
	
	//추상 필드
	String name;
	int age;

	public AnimalType() {} 	// 기본 생성자
	
	public void input(String name, int age) {
		this.age = age;
		this.name = name;
		
		this.howl();
	}

	public void howl() {
		System.out.println( "내 이름은 " + name + "내 나이는 " + age);
	}
	
	// 추상메서드 
	// 하위클래스에서 무조건 구현을 해야함
	abstract void force();
	
}

package abstractEx;

public class Cat extends AnimalType{
	
	String name;
	int age;
	
	public void input(String name, int age) {
		
		this.age = age;
		this.name = name;
		
		this.howl();
	}
	
	public void howl() {
		System.out.print("\""+ "니아옹~" + "\"" + " 내 이름은 " + name + " 내 나이는 " + age + "이다 냐옹~");
	}
	
	
	public void force() {
		System.out.println("강제로 구현해야하는 메소드");
	}
    
    
    package abstractEx;

public class Dog extends AnimalType{
	String name;
	int age;
	
	
	public void input(String name, int age) {
		this.age = age;
		this.name = name;
	
		this.howl();
	}
	
	public void howl() {
		System.out.print("\""+ "왈왈!" + "\"" + " 내 이름은 " + name + " 내 나이는 " + age + "이다 멍!");
	}
	
	public void force() {
		System.out.println("강제로 구현해야하는 메소드");
	}

 

추상화와 다형성의 차이
추상화는 abstract 다형성은 interface입니다.
추상화는 필드, 생성자, 상수, 메서드 등을 포함할 수 있습니다.
다형성은 메서드와, default method만을 포함할 수 있습니다.

 

추상화과 다형성의 공통점
하위클래스의 메서드 구현을 강제합니다.

다형성을 사용하는 이유
추상화가 확실히 다형성보다 많은 기능을 제공하는 것처럼 보입니다. 그렇다면 다형성을 사용해야할 이유가 있을까요?
다형성은 추상화보다 더 추상화된 개념입니다. 클래스로 치지도 않습니다. 이러한 특성이 다중 상속을 가능하게 만듭니다.
(다중 상속이란 하위 클래스들은 하나의 부모 클래스만 가질 수 있는 원칙에 반하는 상속입니다. 즉, 여러 부모 클래스를 가질 수 있게 된다는 의미입니다.)

 

default method란
인터페이스 내에서 메서드를 구현할 수 있습니다.(원래는 추상 메서드만 존재해야합니다.)
만약 default method가 있는 인터페이스를 다중 상속하려 할 때 오버라이딩을 해주지 않는다면 에러가 발생합니다. 오버라이딩을 사용해야 합니다.

default method의 사용 이유
인터페이스의 하위 클래스에 구현을 강제하는 특성이 가져오는 불편함 때문입니다. 예를 들어 인터페이스를 수정해야 하는 상황이 왔을 때 새로운 추상 메서드를 추가한다면
하위 클래스 모두가 수정해야 하는 불상사가 발생합니다. 하지만 default method를 추가해주면 불상사를 방지할 수 있습니다.

 

예제 코드

interface MyInterface{
	//default 메서드 생성
	default void printHello(){
		System.out.println("Hello World!");
	}
}

public class MyClass implements MyInterface {}

public class Main{
	public static void main(String[] args){
		MyClass myClass = new MyClass();

		myClass.printHello();
	}
}

output

Hello World!