[Java] 상속 ④

kiteB·2022년 1월 5일
0

Java

목록 보기
16/35
post-thumbnail

[ 추상 클래스 ]

1. 추상 클래스의 개념

객체를 직접 생성할 수 있는 클래스를 실체 클래스, 실체 클래스들의 공통적인 특성을 추출해서 선언한 클래스를 추상 클래스(abstract class)라고 한다.

  • 추상 클래스가 부모, 실체 클래스가 자식인 상속 관계를 갖는다.
    • 실체 클래스는 추상 클래스의 모든 특성을 물려받고, 추가적인 특성(필드와 메소드)을 가질 수 있다.
  • 추상 클래스는 실체 클래스의 공통되는 필드와 메소드를 추출해서 만들었기 때문에 객체를 직접 생성해서 사용할 수 없다.
    즉, 추상 클래스는 new 연산자를 사용해서 인스턴스를 생성하지 못한다.
  • 추상 클래스는 새로운 실체 클래스를 만들기 위한 부모 클래스의 용도로만 사용된다.

2. 추상 클래스의 용도

1. 실체 클래스들의 공통된 필드와 메소드의 이름을 통일할 목적

실체 클래스를 설계하는 사람이 여러 명일 경우, 실체 클래스마다 필드와 메소드가 제각기 다른 이름을 가질 수 있다.
하지만 추상 클래스에 공통적인 필드와 메소드를 선언해 두고, 이를 상속받아 사용하면 되므로 필드와 메소드 이름을 통일시킬 수 있다.

2. 실체 클래스를 작성할 때 시간 절약

공통적인 필드와 메소드는 추상 클래스에 모두 선언해 두고, 실체 클래스마다 다른 점만 실체 클래스에 선언하게 되면 실체 클래스를 작성하는데 시간을 절약할 수 있다.


3. 추상 클래스 선언

추상 클래스를 선언할 때는 abstract 키워드를 붙여야 한다.
abstract 키워드를 붙이게 되면 new 연산자를 이용하여 객체를 만들지 못하고 상속을 통해 자식 클래스만 만들 수 있다.

public abstract class 클래스이름 {
    //필드
    //생성자
    //메소드
}

추상 클래스도 일반 클래스와 마찬가지로 필드, 생성자, 메소드 선언을 할 수 있다.
new 연산자로 직접 생성자를 호출할 수는 없지만, 자식 객체가 생성될 때 super(...)를 호출해서 추상 클래스 객체를 생성하므로 추상 클래스도 생성자가 반드시 있어야 한다.

예제

  • Phone 클래스 (추상 클래스)
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("폰 전원을 끕니다.");
    }
    
}
  • SmartPhone 클래스 (Phone 추상 클래스를 상속 받은 실체 클래스)
public class SmartPhone extends Phone {
    //생성자
    public SmartPhone(String owner) {
        super(owner);
    }
    
    //메소드
    public void internetSearch() {
        System.out.println("인터넷 검색을 합니다.");
    }
}
  • PhoneExample
public class PhoneExample {
    public static void main(String[] args) {
        //Phone phone = new Phone();	//불가!
        
        SmartPhone smartPhone = new SmartPhone("A");
        
        smartPhone.turnOn();	//Phone의 메소드
        smartPhone.internetSearch();
        smartPhone.turnOff();	//Phone의 메소드
    }
}

4. 추상 메소드와 오버라이딩

메소드의 선언만 통일하고, 실행 내용은 실체 클래스마다 달라야 하는 경우도 있을 것이다.
이런 경우를 위해 추상 클래스는 추상 메소드를 선언할 수 있다.

추상 메소드는 추상 클래스에서만 선언할 수 있는 메소드로, 메소드의 선언부만 있고 메소드 실행 내용인 중괄호 {}가 없는 메소드를 말한다.

추상 클래스를 설계할 때, 하위 클래스가 반드시 실행 내용을 채우도록 강요하고 싶은 메소드가 있을 경우, 해당 메소드를 추상 메소드로 선언하면 된다.

추상 메소드를 선언하는 방법은 다음과 같다.

[public | protected] abstract 리턴타입 메소드명(매개변수, ...);

일반 메소드 선언과의 차이점은 abstract 키워드가 붙어 있고, 메소드 중괄호 {}가 없다는 것이다.

예제

  • Animal 클래스 (추상 클래스)
public abstract class Animal {

    public String kind;
    
    public void breath() {
        System.out.println("숨을 쉽니다.");
    }
    
    public abstract void sound(); 
}
  • Dog 클래스 (Animal 추상 클래스를 상속 받은 실체 클래스)
public class Dog extends Animal {
   public Dog() {
       this.kind = "포유류";
   }
   
   @Override
   public void sound() {	//추상 메소드 재정의
       System.out.println("멍멍");
   }
}
  • Cat 클래스 (Animal 추상 클래스를 상속 받은 실체 클래스)
public class Cat extends Animal {
   public Cat() {
       this.kind = "포유류";
   }
   
   @Override
   public void sound() {	//추상 메소드 재정의
       System.out.println("야옹");
   }
}
  • AnimalExample
public class AnimalExample {
    public static void main(String[] args) {
        
        Dog dog = new Dog();
        Cat cat = new Cat();
        
        dog.sound();	//멍멍
        cat.sound();	//야옹
        
        //변수의 자동 타입 변환
        Animal animal = null;
        animal = new Dog();	//자동 타입 변환
        animal.sound();	//멍멍
        
        animal = new Cat();	//자동 타입 변환
        animal.sound();	//야옹
        
        //메소드의 다형성
        animalSound(new Dog());	//멍멍
        animalSound(new Cat());	//야옹
        
        public static void animalSound(Animal animal) {
            animal.sound();	//재정의된 메소드 호출
        }
    }
}
profile
🚧 https://coji.tistory.com/ 🏠

0개의 댓글