코딩 이야기
JAVA 추상 클래스 본문
객체를 직접 생성 할 수 있는 클래스를 실체 클래스라고 한다면 이 클래스들의 공통적인 특성을 추출해서 선언한 클래스를 추상클래스라고 합니다. 추상클래스와 실체 클래스는 상속관계이며 추상이 부모 실체가 자식관계이다. 실체클래스는 추상클래스의 모든 특성을 물려받고, 추가적인 특성을 가질 수 있다.
여기서 말하는 특성은 필드와 메소드이다. 실체클래스에서 공통되는 필드와 메소드를 따로 선언한 클래스를 만들 수 있는데 이것이 추상클래스이다.
추상 클래스의 용도
실체 클래스의 공통적인 특성(필드, 메소드)를 뽑아내어 추상 클래스로 만드는 이유는 두 가지가 있습니다.
1. 공통된 필드와 메소드의 이름을 통일할 목적
데이터와 기능이 모두 동일함에도 불구하고 이름이 다르다보니, 객체마다 사용방법이 달라 추상 클래스에 필드와 메소드를 선언하고 상속함으로써 필드와 메소드 이름을 통일할 수 있습니다.
2.실체 클래스를 작성할 때 시간 절약
공통적인 필드와 메소드는 추상클래스에 모두 선언해두고, 다른 점만 실체 클래스에 선언하면 실체 클래스를 작성하는데 시간을 절약할 수 있습니다.
추상 클래스 선언
추상 클래스를 선언할 때에는 클래스 선언에 abstract 키워드를 붙여야 합니다. abstract를 붙이면 new 연산자를 이용해서 객체를 만들지 못하고, 상속을 통해 자식 클래스만 만들 수 있습니다.
public abstract class 클래스 {
//필드
//생성자
//메소드
}
추상 클래스도 일반 클래스와 마찬가지로 필드, 생성자, 메소드 선언을 할 수 있습니다. new 연산자로 직접 생성자를 호출할 수는 없지만 자식 객체가 생성될 때 super(...)를 호출해서 추상 클래스 객체를 생성하므로 추상 클래스도 생성자가 반드시 있어야 합니다.
다음 예제는 Phone 클래스를 추상 클래스로 선언한 것입니다.
추상 클래스
package ch07;
public class Phone {
// 필드
public String owner;
// 생성자
public Phone (String owner) {
this.owner = owner;
}
// 메소드
public void turnOn() {
System.out.println("폰 전원을 킵니다.");
}
public void turnOff() {
System.out.println("폰 전원을 끕니다.");
}
}
실체 클래스
Phone 추상 클래스를 상속해서 SmartPhone 자식 클래스를 정의한 것입니다. SmartPhone 클래스의 생성자를 보면 6라인의 super(owner); 코드로 Phone 생성자를 호출하고 있습니다.
package ch07;
public class SmartPhone extends Phone {
//생성자
public SmartPhone(String owner) {
super(owner);
}
//메소드
public void internetSearch() {
System.out.println("인터넷 검색을 합니다.");
}
}
실행 클래스
다음 PhoneExample 클래스의 5라인은 Phone의 생성자를 호출해서 객체를 생성할 수 없음을 보여줍니다. 대신 자식 클래스인 SmartPhone으로 객체를 생성해서 Phone의 메소드인 turnOn(), tuenOff() 메소드를 사용할 수 있습니다.
package ch07;
public class PhoneExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Phone phone = new Phone();
SmartPhone smartPhone = new SmartPhone("홍길동");
smartPhone.turnOn(); // phone의 메소드
smartPhone.internetSearch();
smartPhone.turnOff(); // phone의 메소드
}
}
* 추상 클래스는 실체 클래스의 공통되는 필드와 메소드를 추출해서 만들었기 때문에 객체를 직접 생성해서 사용할 수 없습니다.
Ainmal animal = new Animal(); // (x)
* 추상 클래스는 새로운 실체 클래스를 만들기 위해 부모 클래스로만 사용됩니다. 코드로 설명하면 추상 클래스는 extends뒤에만 올 수 있는 클래스입니다.
class Ant extends Animal {...} // (o)
추상 메소드와 재정의
메소드의 선언만 동일하고 실행 내용은 실체 클래스마다 달라야 하는경우 추상 클래스는 추상 메소드를 선언할 수 있습니다. 추상 메소든느 abstract키워드와 함께 메소드의 선언부만 있고 메소드 실행 내용인 중괄호 {}가 없는 메소드를 말합니다. 다음은 추상 메소드는 선언하는 방법입니다.
[public | protected] abstract 리턴타입 메소드이름( 매개 변수, ...);
추상 클래스 설계 시 하위 클래스가 반드시 실행 내용을 채우도록 강제하고 싶은 메소드가 있을 경우 해당 메소드를 추상 메소드로 선언합니다. 자식 클래스는 추상 메소드를 재정의해서 실행 내용을 작성해야 하는데, 그렇지 않으면 컴파일 에러가 발생합니다.
추상 메소드 선언(Ainmal)
package ch07;
public abstract class Animal { // 추상 클래스
public String kind;
public void breathe() {
System.out.println("숨을 쉽니다.");
}
public abstract void sound();
}
추상 메소드 재정의(dog)
package ch07;
public class Dog extends Animal {
public Dog() {
this.kind = "포유류";
}
@Override
public void sound() {
System.out.println("멍멍"); // 추상 메소드 재정의
}
}
추상 메소드 재정의(Cat)
package ch07;
public class Cat extends Animal {
public Cat() {
this.kind = "포유류";
}
@Override
public void sound() {
System.out.println("야옹"); // 추상 메소드 재정의
}
}
실행 클래스
package ch07;
public class AnimalExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog = new Dog();
Cat cat = new Cat();
dog.sound();
cat.sound();
System.out.println("-------");
// 변수의 자동 타입 변환
Animal animal = null;
animal = new Dog();
animal.sound();
animal = new Cat();
animal.sound();
System.out.println("-------");
// 메소드의 다형성
animalSound(new Dog());
animalSound(new Cat());
}
public static void animalSound(Animal animal) {
animal.sound();
}
}
'JAVA' 카테고리의 다른 글
JAVA 타입변환과 다형성(인터페이스) (0) | 2023.02.16 |
---|---|
JAVA 인터페이스 (0) | 2023.02.15 |
JAVA 객체타입확인 (0) | 2023.02.15 |
JAVA 타입변환과 다형성 (0) | 2023.02.13 |
JAVA 메소드 재정의 (0) | 2023.02.13 |