본문 바로가기

Java/본격 Java 퀴즈 기초

[Java] 원과 직사각형 추상클래스로 상속받아 구현하기

원과 직사각형의 넓이와 둘레를 구하는 식을 구현해보자.

그러면 원과 직사각형의 상위 클래스인 Shape 클래스를 만든다.

.

.

package AbstractShape;

public abstract class Shape {
	String color;
	boolean filled;
	
	public Shape() {}
	
	public Shape(String color, boolean filled) {
		this.color = color;
		this.filled = filled;
	}
	public String getColor() { return color; }
	public void setColor(String color) { this.color = color; }
	public boolean isFilled() { return filled; }
	public void setFilled(boolean filled) { this.filled = filled; }
	
	public double getArea() { return 0; }
	public double getPerimeter() { return 0; }
	@Override
	public String toString() {
		return "Shape [color=" + color + ", filled=" + filled + "]";
	}
}

.

.

상위클래스에서는 하위클래스들이 필수적으로 구현해야할 넓이 구하는 메소드와 둘레구하는 메소드를 추상클래스에서 구현한다.

.

.

그리고 상위 추상클래스를 상속받을 원클래스와 직사각형클래스를 작업한다

.

.

<Circle Class>

package AbstractShape;
import java.math.*;

public class Circle extends Shape{
	double radius = 1.0;
	public Circle() {}
	public Circle(double radius) {
		super();
		this.radius = radius;
	}
	public Circle(double radius, String color, boolean filled) {
		super(color, filled);
		this.radius = radius;
	}
	
	public double getRadius() { return radius; }
	public void setRadius(double radius) { this.radius = radius; }
	
	public double getArea() {
		return radius * radius * Math.PI;
	}
	
	public double getPerimeter() {
		return radius * 2 * Math.PI;
	}
	
	@Override
	public String toString() {
		return "Circle [radius=" + radius + "]";
	}
}

.

.

<Rectangle Class>

package AbstractShape;

public class Rectangle extends Shape{
	double width, length;
	
	public Rectangle() {}
	public Rectangle(double width, double length) {
		this.width = width;
		this.length = length;
	}
	public Rectangle(double width, double length, String color, boolean filled) {
		super(color, filled);
		this.width = width;
		this.length = length;
	}
	public double getWidth() { return width; }
	public void setWidth(double width) { this.width = width; }
	public double getLength() { return length; }
	public void setLength(double length) { this.length = length; }
	
	public double getArea() {
		return width * length;
	}
	public double getPerimeter() {
		return 2 * (width + length);
	}
	@Override
	public String toString() {
		return "Rectangle [width=" + width + ", length=" + length + "]";
	}
	
}

.

.

각각 클래스에서는 상위클래스에서 구현한 넓이구하는 메소드랑 둘레구하는 메소드를 오버라이딩해서 구현하였다.

.

.

지금은 직사각형클래스를 상속받는 정사각형클래스를 구현해보자

.

.

package AbstractShape;

public class Square extends Rectangle{
	public Square(){}
	public Square(double side) {
		super(side, side);
	}
	public Square(double side, String color, boolean filled) {
		super(side, side, color, filled);
	}
	
	public double getSide() { return super.getLength(); }
	public void setSide(double side) { super.setLength(side); super.setWidth(side); }
	public void setWidth(double side) { super.setWidth(side); }
	public void setLength(double side) { super.setLength(side); }
	
	@Override
	public String toString() {
		return "Square []";
	}
	
}

.

.

최상위클래스에서 구현된 메소드들은 그 다음 클래스에서는 구현하지 않아도 된다.

.

.

테스트를 한 번 해보자

.

.

package AbstractShape;

public class TestShape {

	public static void main(String[] args) {
		Shape s1 = new Circle(5.5, "RED", false); // Upcast Circle to Shape
		System.out.println(s1);
		System.out.println(s1.getArea());
		System.out.println(s1.getPerimeter());
		System.out.println(s1.getColor());
		System.out.println(s1.isFilled());
		System.out.println();
		
		Circle c1 = (Circle)s1; // Downcast back to Circle
		System.out.println(c1);
		System.out.println(c1.getArea());
		System.out.println(c1.getPerimeter());
		System.out.println(c1.getColor());
		System.out.println(c1.isFilled());
		System.out.println(c1.getRadius());
		System.out.println();
		
		// Shape s2 = new Shape(); // 추상화 클래스는 선언이 안된다?
		
		Shape s3 = new Rectangle(1.0, 2.0, "RED", false); // Upcast
		System.out.println(s3);
		System.out.println(s3.getArea());
		System.out.println(s3.getPerimeter());
		System.out.println(s3.getColor());
		// System.out.println(s3.getLength()); // 상위클래스로 선언하고 하위클래스 객체로는 하위클래스에 있는 메소드를 사용할 수 없다?
		System.out.println();
		
		Rectangle r1 = (Rectangle)s3; // Downcast
		System.out.println(r1);
		System.out.println(r1.getArea());
		System.out.println(r1.getPerimeter());
		System.out.println(r1.getColor());
		System.out.println(r1.getLength());
		System.out.println();
		
		Shape s4 = new Square(6.6); // Upcast
		System.out.println(s4);
		System.out.println(s4.getArea());
		System.out.println(s4.getPerimeter());
		System.out.println(s4.getColor());
		// System.out.println(s4.getSide());
		System.out.println();
		
		Rectangle r2 = (Rectangle)s4; // DownCast
		System.out.println(r2);
		System.out.println(r2.getArea());
		System.out.println(r2.getPerimeter());
		System.out.println(r2.getColor());
		System.out.println(r2.getLength());
		// System.out.println(r2.getSide());
		System.out.println();
		
		Rectangle sq1 = (Square)r2; // Downcast
		System.out.println(sq1);
		System.out.println(sq1.getArea());
		System.out.println(sq1.getPerimeter());
		// System.out.println(sq1.getSide());
		System.out.println(sq1.getLength());
		System.out.println();
	}

}

.

.

Upcast를 하면 객체로 선언된 메소드들을 사용할 수 없지만

Downcast를 하게되면 해당 객체에 메소드를 사용할 수 있다.

 

728x90
반응형