백엔드 수업 #07 상속 - 08 추상 클래스

sookyoung.k·2022년 12월 1일
0
post-thumbnail

헐 나 이제 그림 이모티콘을 어떻게 쓰는지 알게 되었다. 오... 더 예쁘게 정리해봐야지

✔ 추상 클래스의 개념

abstract: 추상
→ 실체 간에 공통되는 특성을 추출한 것

실체 클래스: 객체를 직접 생성할 수 있는 클래스
추상 클래스: 이 클래스들의 공통적인 특성을 추출해서 선언한 클래스

추상 클래스와 실체 클래스는 상속의 관계를 가지게 된다. (실체 클래스가 추상 클래스의 특성을 가져와서 사용해야 하니까!)
추상 클래스가 부모 클래스이고 실체 클래스가 자식 → 실체 클래스는 추상 클래스의 모든 특성을 물려받고 추가적인 특성을 가질 수 있다. (특성: 필드와 메소드)

  • 추상 클래스는 실체 클래스의 공통되는 필드와 메소드를 추출해서 만들었기 때문에 객체를 직접 생성해서 사용할 수는 없다.

✔ 추상 클래스의 용도

  1. 실체 클래스들의 공통된 필드와 메소드 이름을 통일하기 위함
  2. 실체 클래스를 작성할 때 시간을 절약할 수 있음

✔ 추상 클래스 선언

클래스 선언에 abstract 키워드를 붙이면 된다.

이렇게 되면 new 연산자를 이용해서 객체를 만들 수 없고 상속을 통해 자식 클래스만 만들 수 있다.

추상 클래스도 일반 클래스와 마찬가지로 필드, 생성자, 메소드 선언을 할 수 있다.

new 연산자로 직접 생성자를 호출할 수는 없지만 자식 객체가 생성될 때 super(...)를 호출해서 추상 클래스 객체를 생성하기 때문에 추상 클래스도 반드시 생성자가 필요하다.

public abstract class Phone { // 추상클래스 
	// 필드
    public String owner;
    
    // 생성자
    public Phone(String owner) {
    	this.owner = owner; 
    }
    
    // 메소드
    public void turnOn() {
    	System.out.println("폰 전원을 켭니다.")
    }
    public void turnOff() {
    	System.out.println("폰 전원을 끕니다.")
    }
}

public class SmartPhone extends Phone { // 실체 클래스 
	// 생성자 
   	public SmartPhone(String owner) {
    	super(owner);
   	}
    
   	// 메소드
    public void internetSearch() {
     	System.out.println("인터넷 검색을 합니다.");
    }
}

public class SmartPhoneEX {

	public static void main(String[] args) {
		//Phone phone = new Phone(); // Phone의 생성자를 호출해서 객체를 생성할 수는 없다. 
        
        SmartPhone smartPhone = new SmartPhone("홍길동") // 대신 자식 클래스로 객체 생성!
    
   		smartPhone.turnOn(); // Phone의 메소드 호출 
   		smartPhone.internetSearch();
   		smartPhone.turnOff(); // Phone의 메소드 호출 

}

[출력 결과]
폰 전원을 켭니다.
인터넷 검색을 합니다.
폰 전원을 끕니다.

✔ 추상 메소드와 오버라이딩

추상 클래스의 목적: 실체 클래스의 멤버(필드와 메소드)를 통일화 하는 것.

모든 실체들이 가지고 있는 메소드의 실행 내용이 동일하다면 추상 클래스에 메소드를 작성하는 것이 좋다.

하지만! 메소드의 선언만 통일하고 실행 내용은 달라야 하는 경우라면?

추상 메소드를 선언하면 실행 내용을 변경할 수 있다!

  • 추상 메소드는 추상 클래스에서만 선언이 가능!
  • 메소드의 선언부만 있고 메소드 실행 내용인 중괄호가 없는 메소드를 말함!
  • 자식 클래스는 반드시 추상 메소드를 재정의(오버라이딩)해서 실행 내용을 작성해야 한다.
public abstract class Animal { // 추상 클래스 생성! ^0^ (상속을 하기 위해서 만들어짐)
	// 일반 메소드
	public void breathe() {
		System.out.println("숨을 쉽니다.");
	}
	
	// 추상 메소드
	// 추상 메소드는 자식클래스에서 반드시 오버라이딩이 되어야 한다. 
	public abstract void sound();
	
}

public class Dog extends Animal {

	@Override
	public void sound() {
		System.out.println("멍멍"); // 추상 메소드 재정의! 
	}
	
}

public class Cat extends Animal {

	@Override
	public void sound() {
		System.out.println("냥냥");
	}

}

public class AbstractEX {

	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.sound();
		
		Cat cat = new Cat();
		cat.sound();
		
		// 매개변수 다형성 (자동형변환)
		animalSound(dog); // = animalSound(new Dog());
		animalSound(cat); // = animalSound(new Cat());
	}

	// * 메소드의 다형성 구현: 다형성을 하려면 일단 메소드가 있어야 함
	public static void animalSound(Animal animal) {
		animal.sound(); // 재정의된 메소드 호출
	}
}

[출력 결과]
멍멍
냥냥
멍멍
냥냥

profile
영차영차 😎

0개의 댓글