기본적인 자바에 대해 부족한 부분을 보충해서 포스팅 해봅니다 크롬에 최적화 되어있습니다.
추상메소드
추상 메소드란 메소드의 시그니처만이 정의된 비어있는 메소드를 의미한다. 아래의 코드를 보자.
package org.opentutorials.javatutorials.abstractclass.example1;
abstract class A{
public abstract int b();
//본체가 있는 메소드는 abstract 키워드를 가질 수 없다.
//public abstract int c(){System.out.println("Hello")}
//추상 클래스 내에는 추상 메소드가 아닌 메소드가 존재 할 수 있다.
public void d(){
System.out.println("world");
}
}
public class AbstractDemo {
public static void main(String[] args) {
A obj = new A();
}
}
- 위 코드의 실행 결과는 아래와 같다.
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot instantiate the type A
at org.opentutorials.javatutorials.abstractclass.example1.AbstractDemo.main(AbstractDemo.java:7)
메소드 b의 선언 부분에는 abstract라는 키워드가 등장하고 있다. 이 키워드는 메소드 b는 메소드의 시그니처만 정의 되어 있고 이 메소드의 구체적인 구현은 하위 클래스에서 오버라이딩 해야 한다는 의미다. 이렇게 내용이 비어있는 메소드를 추상 메소드라고 부른다. 추상 메소드를 하나라도 포함하고 있는 클래스는 추상 클래스가 되고, 자연스럽게 클래스의 이름 앞에 abstract가 붙는다.
에스프레소 문제
package ex01_abstract;
/*
* 추상 메소드
* 1. abstract method
* 2. 형태가 없는 메소드
* 3. 본문이 없는 메소드
* 4. 작성 방법
* abstract 결과타입 메소드명(매개변수);
*
* 추상 클래스
* 1. abstract class
* 2. 형태가 없는 클래스
* 3. new가 불가능한 클래스
* 4. 추상 메소드를 하나라도 가지고 있으면 추상 클래스
* 5. 작성 방법
* abstract class 클래스명 {
* abstract 결과타입 메소드명(매개변수);
* }
* 6. 추상 클래스를 상속 받는 서브클래스들은
* 반드시 추상 메소드를 오버라이드 해야 한다.
*/
abstract class Coffee {
// field
private String beanOrigin;
// constructor
public Coffee(String beanOrigin) {
super();
this.beanOrigin = beanOrigin;
}
// method
// 일반 메소드
public void info() {
System.out.println("커피원산지: " + beanOrigin);
}
// 추상 메소드 (본문을 작성할 필요가 없는 메소드)
public abstract void taste();
}
class Espresso extends Coffee {
// field
private int water;
// constructor
public Espresso(String beanOrigin, int water) {
super(beanOrigin);
this.water = water;
}
// method
// 일반 메소드는 오버라이드를 하던지 말던지 알아서 처리
// 추상 메소드는 반드시 오버라이드를 해야 함
@Override
public void info() {
super.info(); // 커피원산지
System.out.println("물의 양: " + water);
}
@Override
public void taste() {
System.out.println("Espresso는 쓰다.");
}
}
class Latte extends Espresso {
// field
private int milk;
// constructor
public Latte(String beanOrigin, int water, int milk) {
super(beanOrigin, water);
this.milk = milk;
}
// method
@Override
public void info() {
super.info(); // 커피원산지, 물
System.out.println("우유의 양: " + milk);
}
@Override
public void taste() {
System.out.println("Latte는 부드럽다.");
}
}
public class Ex01_Coffee {
public static void main(String[] args) {
// new Coffee("콜롬비아"); // 추상 클래스는 new를 할 수 없다.
Coffee[] list = new Coffee[2]; // 객체 생성하는 new가 아님
list[0] = new Espresso("탄자니아", 30);
list[1] = new Latte("케냐", 30, 150);
for (Coffee coffee : list) {
if (coffee != null) {
coffee.info();
coffee.taste();
}
}
}
}
결과값
아래 예제는 abstrct 를 이용한 계산기 문제 입니다.
계산기 문제
package practice;
abstract class Calculator{
int left, right;
public void setOprands(int left, int right){
this.left = left;
this.right = right;
}
public abstract void sum();
public abstract void avg();
public void run(){
sum();
avg();
}
}
class CalculatorDecoPlus extends Calculator {
public void sum(){
System.out.println("+ sum :"+(this.left+this.right));
}
public void avg(){
System.out.println("+ avg :"+(this.left+this.right)/2);
}
}
class CalculatorDecoMinus extends Calculator {
public void sum(){
System.out.println("- sum :"+(this.left+this.right));
}
public void avg(){
System.out.println("- avg :"+(this.left+this.right)/2);
}
}
public class Q01_abstract {
public static void main(String[] args) {
CalculatorDecoPlus c1 = new CalculatorDecoPlus();
c1.setOprands(10, 20);
c1.run();
CalculatorDecoMinus c2 = new CalculatorDecoMinus();
c2.setOprands(10, 30);
c2.run();
}
}