1. 추상메소드(abstract method)
추상 클래스를 알아보기 전에 추상메소드(abstract method)부터 알아보겠습니다.
추상메소드는 보디(body)가 없고 껍데기만 있는 메소드입니다.
abstract 리턴타입 메소드명();
위와 같이 선언만 되어있고 구현되지 않은 메소드입니다.
선언할 때 abstract 키워드를 사용합니다.
구현되어 있지 않기 때문에 {}를 사용할 필요 없이 세미콜론(;)으로 문장이 끝났습니다.
이런 추상메소드는 상속받는 자식 클래스에서 반드시 구현이 되어야 합니다.
즉, 오버라이딩되어야만 사용할 수 있는 메소드입니다.
만약 자식 클래스에서도 구현되지 않았다면 그 자식의 자식 클래스에서 구현이 되어야 하겠네요.
공통적인 부분은 미리 만들어진 것을 사용하지만 상속받아 사용하는 쪽에서는 필요한 부분만 재정의하여 사용하게 되면 생산성이 향상되고 배포가 쉬워질 수 있습니다.
2. 추상클래스(abstract class)
그렇다면 추상 클래스는 무엇일까요??
추상 클래스는 하나 이상의 추상메소드를 포함하고 있는 클래스입니다.
추상 클래스에서 반드시 필요한 메소드를 추상메소드로 선언해 놓으면 자식 클래스에서는 해당 메소드를 반드시 구현해야 합니다.
abstract class 클래스명{
abstract 리턴타입 메소드명();
}
추상 클래스도 abstract 키워드로 선언하며 형태는 위와 같다고 볼 수 있습니다.
Animal.java
package com.test01;
public abstract class Animal {
public abstract void bark();
public void eat(String food) {
System.out.println(food + "먹는다.");
}
}
Cat.java
package com.test01;
public class Cat extends Animal {
@Override
public void bark() {
System.out.println("야옹");
}
@Override
public void eat(String feed) {
System.out.print("고양이가 ");
super.eat(feed);
}
}
Dog,java
package com.test01;
public class Dog extends Animal {
@Override
public void bark() {
System.out.println("멍멍");
}
@Override
public void eat(String feed) {
System.out.print("멍멍이가 ");
super.eat(feed);
}
}
MTest.java
package com.test01;
public class MTest {
public static void main(String[] args) {
//Animal animal = new Animal(); //바디가 없어서 오류 -> 추상클래스는 객체선언 불가
Animal cat = new Cat();
Animal dog = new Dog();
cat.bark();
dog.bark();
cat.eat("생선");
dog.eat("뼈다귀");
}
}
위의 코드를 보면 Animal 클래스가 추상 메소드로 선언되어 있으며 bark()메소드가 추상메소드로 선언되어 있습니다.
그리고 Cat 클래스와 Dog 클래스는 Animal 클래스를 상속받고 있습니다.
Cat 클래스, Dog 클래스에서 bark()메소드가 반드시 구현되어야 합니다.
위의 코드에서는 Cat 클래스와 Dog 클래스에서 bark()메소드가 구현이 되어있죠?
MTest 클래스에서 Animal animal = new Animal();로 Animal 타입으로 Animal 객체를 생성했지만 오류가 발생합니다.
추상 클래스는 객체를 생성할 수 없습니다!
bark가 Animal의 자식 클래스에서 구현되어 있기 때문에 객체지향프로그래밍의 특성 중 하나인 다형성으로 Cat과 Dog의 객체를 생성할 수 있습니다.
Animal.java
package com.test02;
public abstract class Animal {
public Animal() {
System.out.println("동물 : ");
}
public abstract void start();
public abstract void stop();
}
Cat.java
package com.test02;
public class Cat extends Animal {
public Cat() {
System.out.println("고양이");
}
@Override
public void start() {
System.out.println("고양이가 사뿐사뿐 걷는다.");
}
@Override
public void stop() {
System.out.println("고양이가 멈췄다.");
}
}
Dog.java
package com.test02;
public class Dog extends Animal {
public Dog() {
System.out.println("멍멍이");
}
@Override
public void start() {
System.out.println("멍멍이가 촐랑촐랑 걷는다.");
}
@Override
public void stop() {
System.out.println("멍멍이가 멈췄다.");
}
}
Elephant.java
package com.test02;
public class Elephant extends Animal {
public Elephant() {
System.out.println("코끼리");
}
@Override
public void start() {
System.out.println("도토가 쿵쿵 걷는다.");
}
@Override
public void stop() {
System.out.println("도토가 멈췄다.");
}
}
MTest.java
package com.test02;
import java.util.Scanner;
public class Mtest {
/*
* 동적 바인딩 : 실행시 메모리 할당을 하면서 메소드를 동적으로 연동하는 방식
* 1. 코드 절약 2. 실행속도 향상 3. 행위 은닉
*/
public static void main(String[] args) {
System.out.println("선택해 주세요\n[1:고양이 2:멍멍이 3:도토]");
Scanner sc = new Scanner(System.in);
int select = sc.nextInt();
Animal animal = null;
switch(select) {
case 1:
animal = new Cat();
break;
case 2:
animal = new Dog();
break;
case 3:
animal = new Elephant();
break;
}
animal.start();
animal.stop();
}
}
이 코드의 경우도 Animal 클래스가 추상 클래스이기 때문에 객체 생성이 불가능합니다.
또한 Animal 클래스에 있는 추상메소드는 자식 클래스인 Cat, Dog, Elephant 클래스에 구현이 되어있어서 자식 클래스는 객체 생성이 가능합니다.
MTest 클래스의 메인메소드를 보시면 코드가 실행되고 Scanner()를 통해 번호가 입력되면 메모리가 할당됩니다.
이러한 것을 동적 바인딩이라고 하는데 코드가 절약되고, 실행 속도가 향상되는 장점이 있습니다.
추상 클래스는 객체를 만들 수 없다.
추상 클래스는 하나 이상의 추상 클래스를 가지고 있다.
추상메소드는 자식 클래스에서 반드시 구현되어야 한다.
클래스는 다중 상속이 불가능하다. 추상 클래스도 클래스기 때문에 다중 상속이 불가능하다.
추상 클래스는 생성자나 다른 메소드를 포함할 수 있다.
이 정도로 정리하면 될까요??
'Java 관련 > Java' 카테고리의 다른 글
[Java] 내부 클래스(inner class) (0) | 2021.11.08 |
---|---|
[Java] 인터페이스(interface)를 이용한 도형의 넓이 구하기 & 캡슐화 (0) | 2021.11.07 |
[Java] 상속과 다형성 (0) | 2021.11.05 |
[Java] 다형성(polymorphism) (0) | 2021.11.04 |
[Java] 상속(inheritance) (0) | 2021.11.03 |