abstract

codakcodak·2023년 7월 23일
0

Java

목록 보기
13/17
post-thumbnail

abstract

추상메서드

  • 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드
  • 자식 클래스에서 재정의해서 사용하는 메서드는 부모클래스에서의 구현이 의미가 없으므로 추상 메서드로 선언
    *동적 바인딩으로 인해 부모클래스로 참조해도 오버라이드된 자식의 메서드로 사용

추상클래스

  • 추상 메서드를 선언해 놓고 상속을 통해 자식 클래스에서 메서드를 완성하도록 유도하는 클래스
  • 객체화가 불가능하며 추상메서드를 가질 수 있는 클래스(추상 메서드가 없어도 추상클래스를 만들 수 있다.)
  • 구현의 강제를 통해 프로그램의 안정성 향상(자식 클래스에서 추상 부모 클래스의 추상메서드를 오버라이드 하지 않으면 컴파일 에러가 난다.)

문법

  • 추상메서드가 있는 클래스는 추상클래스로 선언 되어야 한다.
public abstract class Vehicle {
	private int curX, curY;

    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }
    public abstract void addFuel();//abstract(추상)메서드가 있으므로 클래스 이름또한 abstact(추상)클래스가 된다.
}
  • 내부에 abstract 메서드가 있다면 자식 클래스에서는 오버라이딩을 해야한다.
abstract class Vehicle {
	private int curX, curY;

    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }
    public abstract void addFuel();
}
public class ElectricCar extends Vehicle{
	@Override
    public void addFuel() {//추상클래스를 상속 받았으므로 추상메서드를 오버라이드 해야한다.
        System.out.printf("차종: %s: 연료 주입: %s%n", this.getClass().getSimpleName(), "충전");
    }
}
  • 자식클래스에서 오버라이딩을 하지 않으면 자식클래스에 abstract 메서드가 남아있으므로 자식클래스 또한 abstract클래스가 되어야 한다.
abstract class Vehicle {
	private int curX, curY;

    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }
    public abstract void addFuel();
}
public abstract class ElectricCar extends Vehicle{
//	@Override  조상클래스의 추상메서드를 오버라이드 하지 않으므로 ElectricCar클래스 또한 추상클래스로 선언해야한다.
//    public void addFuel() {
//        System.out.printf("차종: %s: 연료 주입: %s%n", this.getClass().getSimpleName(), "충전");
//    }
}
  • 구현부가 없는 메서드가 있으므로 객체생성은 불가능하다.
abstract class Vehicle {
	private int curX, curY;

    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }
    public abstract void addFuel();
}
public class VehicleTest{
	public static void main(String[] args) {
		Vehicle vehicle=new Vehicle();//추상클래스이기에 객채생성이 불가능
	}
}
Cannot instantiate the type Vehicle
  • 상위 클래스 타입으로 자식을 참조하는 것이 가능하다.
abstract class Vehicle {
	private int curX, curY;

    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }
    public abstract void addFuel();
}
class ElectricCar extends Vehicle{
	@Override
    public void addFuel() {
        System.out.printf("차종: %s: 연료 주입: %s%n", this.getClass().getSimpleName(), "충전");
    }
}
public class VehicleTest{
	public static void main(String[] args) {
		Vehicle vehicle=new ElectricCar();//부모클래스로 자식클래스를 참조
		vehicle.addFuel();//동적바인딩으로 인해 오버라이딩 된 자식클래스의 addFuel사용
	}
}
차종: ElectricCar: 연료 주입: 충전
  • 추상메서드를 하나도 가지고 있지 않아도 된다.(외부에서 객체생성을 막기 위함)
public abstract class Vehicle {
	private int curX, curY;
    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }
}

코드

추상 클래스,추상 메서드 전

class Vehicle {
	private int curX, curY;

    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }
    public void addFuel() {//(1)
    	System.out.println("연료가 필요합니다!");
    }
}

class DieselSUV extends Vehicle{
    private int curX, curY;

    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }

    public void addFuel() {//(2)
        System.out.printf("차종: %s: 연료 주입: %s%n", this.getClass().getSimpleName(), "경유");
    }
}

class ElectricCar extends Vehicle{
    private int curX, curY;

    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }

    public void addFuel() {//(3)
        System.out.printf("차종: %s: 연료 주입: %s%n", this.getClass().getSimpleName(), "충전");
    }
}

public class VehicleTest{
	public static void main(String[] args) {
		Vehicle[] vehicles= {new DieselSUV(),new ElectricCar()};
		for (Vehicle v:vehicles) {
			v.addFuel();
		}
	}
}
  • Vehicle의 addFuel()(1)메서드는 ElectricCar(2),DieselSUV(3)에서 모두 오버라이딩 하고 있어 구현된 내용이 쓰이고 있지 않다.
  • 모든 자식 클래스에서 재정의 하고 있기 때문에 부모 클래서의 메서드 구현이 무의미하다.
  • 구현부를 없애는 간단한 표현과 자식클래스에서 반드시 구현해야하는 강제성이 필요하다.

추상 클래스,추상 메서드 적용


abstract class Vehicle {
	private int curX, curY;

    public void reportPosition() {
        System.out.printf("차종: %s: 현재 위치: (%d, %d)%n", this.getClass().getSimpleName(), curX, curY);
    }
    public abstract void addFuel();
}

class ElectricCar extends Vehicle{
	@Override
    public void addFuel() {
        System.out.printf("차종: %s: 연료 주입: %s%n", this.getClass().getSimpleName(), "충전");
    }
}

class DieselSUV extends Vehicle{
	@Override
    public void addFuel() {
        System.out.printf("차종: %s: 연료 주입: %s%n", this.getClass().getSimpleName(), "경유");
    }
}


public class VehicleTest{
	public static void main(String[] args) {
		Vehicle[] vehicles= {new DieselSUV(),new ElectricCar(),new Vehicle()};
		for(Vehicle v:vehicles) {
			v.addFuel();
		}
	}
}

생성자관련

  • 추상클래스는 new를 통해 객체를 생성하는 것은 불가능하기에 객체를 생성할때 초기화를 해주는 생성자가 없는줄 알았지만 존재가 가능하다.추상클래스를 상속받은 자식클래스에서 super를 통해 생성자 호출 및 참조가 가능하다.
abstract class Vehicle {
	private int curX, curY;
	Vehicle(int x,int y){//추상클래스의 생성자
		this.curX=x;
		this.curY=y;
	}
    public void reportPosition() {
        System.out.printf("현재 위치: (%d, %d)%n", this.curX, this.curY);
    }
    public abstract void addFuel();
}	
class ElectricCar extends Vehicle{
	ElectricCar(int x,int y){//일반 메서드의 생성자 안에 조상인 추상클래스의 생성자 호출
		super(x,y);
	}
	@Override
    public void addFuel() {
        System.out.printf("차종: %s: 연료 주입: %s%n", this.getClass().getSimpleName(), "충전");
    }
}
public class VehicleTest{
	public static void main(String[] args) {
		Vehicle vehicle1=new ElectricCar(10,10);//ElectricCar를 통해 Vehicle의 curX,curY를 초기화
		vehicle1.reportPosition();
	}
}
현재 위치: (10, 10)
profile
숲을 보는 코더

1개의 댓글

comment-user-thumbnail
2023년 7월 23일

유익한 글이었습니다.

답글 달기