다형성 이해를 위한 상속 정리하기

Minseok-Choi·2022년 1월 13일

스터디

목록 보기
2/8

상속이란?

자바의 정석 상속 강의를 정리하였습니다.

  • 기존의 클래스로 새로운 클래스를 작성하는 것(코드의 재사용)
  • 두 클래스를 부모와 자식으로 관계를 맺어주는 것
class 자식클래스 extends 부모클래스 {
 	// ... 
}
  • 자손은 조상(부모)의 모든 멤버를 상속 받는다. (생성자, 초기화블럭 제외) (마음에 안드는 유전자도 받아야한다.웃프다.)
  • 자손의 멤버 갯수는 조상보다 적을 수 없다.
  • 자손의 변경은 조상에 영향을 미치지 않는다.
class Point {
  	int x;
  	int y;
}
// Point 클래스와 관계없음
class Point3D {
  int x;
  int y;
  int z;
}
// Point 클래스와 관계가 있기 때문에 Point 클래스에서 멤버의 변경이 생기면 멤버의 변경이 생긴다.
class Point3D extends Point {
  	int z; // 멤버가 하나로 보이지만 사실상 3개
}

도형을 통해서 활용해보기

NextStep TDD강의 중 좌표계산기를 통해서 활용 연습하였습니다.
프로그래밍 요구사항은 강의 내에서 확인할 수 있습니다.
개인적으로 연습한 코드이므로 부족한 부분이 많습니다.

  • 좌표를 활용합니다.
  • 각각의 class에 따라서getAnswer() 메서드가 달라집니다.
  • Line은 두 좌표의 길이를 반환
  • Triangle은 삼각형의 넓이를 반환
  • Rectangle은 사각형의 넓이를 반환

Point

import java.util.Objects;

public class Point {
    private static final int MIN = 0;
    private static final int MAX = 24;
    private final int x;
    private final int y;

    Point(int x, int y) {
        rangeCheck(x,y);
        this.x = x;
        this.y = y;
    }

    public double calculateDistance(Point point) {
        return Math.sqrt(Math.pow(this.x - point.x,2) + Math.pow(this.y-point.y,2));
    }

    private void rangeCheck(int x, int y) {
        if( x < MIN || x > MAX ||  y < MIN || y > MAX) {
            throw new IllegalArgumentException();
        }
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Point)) return false;
        Point point = (Point) o;
        return x == point.x && y == point.y;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}

AbstractFigure

import java.util.List;
import java.util.Objects;

public abstract class AbstractFigure implements Figure{

    private final List<Point> points;

    AbstractFigure(List<Point> points) {
        this.points = points;
    }

    @Override
    public List<Point> getPoints() {
        return points;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof AbstractFigure)) return false;
        AbstractFigure that = (AbstractFigure) o;
        return Objects.equals(points, that.points);
    }

    @Override
    public int hashCode() {
        return Objects.hash(points);
    }

}

Line

import java.util.List;

public class Line extends AbstractFigure{
    private static final String MESSAGE_LINE = "두 점 사이 거리는 ";


    public Line(List<Point> points) {
        super(points);
    }

    @Override
    public List<Point> getPoints() {
        return super.getPoints();
    }


    private double calculate() {
        return getPoints().get(0).calculateDistance(getPoints().get(1));
    }

    @Override
    public String getAnswer() {
        return MESSAGE_LINE+String.format("%.6f",calculate());
    }


}

Triangle

import java.util.List;

public class Triangle extends AbstractFigure{
    private static final String MESSAGE_TRIAGNGLE = "삼각형의 넓이는 ";

    Triangle(List<Point> points) {
        super(points);
    }

    @Override
    public List<Point> getPoints() {
        return super.getPoints();
    }

    @Override
    public String getAnswer() {
        return MESSAGE_TRIAGNGLE+String.format("%.1f", calculate());
    }

    private double calculate() {
        Point p1= getPoints().get(0);
        Point p2= getPoints().get(1);
        Point p3= getPoints().get(2);

        double side1 = p1.calculateDistance(p2);
        double side2 = p1.calculateDistance(p3);
        double side3 = p2.calculateDistance(p3);

        double s = (side1+side2+side3)/2;

        return Math.sqrt(s * (s-side1) * (s-side2) * (s-side3));
    }
}

Rectangle

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Rectangle extends AbstractFigure{
    private static final String MESSAGE_RECTANGLE = "사각형의 넓이는 ";
    private static final String NOT_RECTANGLE_ERROR ="좌표 입력을 확인해주세요. 직사각 형태를 가지도록 좌표를 입력해주세요.";
    Rectangle(List<Point> points) {
        super(points);
    }

    @Override
    public List<Point> getPoints() {
        return super.getPoints();
    }

    @Override
    public String getAnswer() {
        return MESSAGE_RECTANGLE+String.format("%.0f",calculate());
    }

    private double calculate() {
        int width = calculateLength(getXvalues());
        int height = calculateLength(getYvalues());
        return (width * height);
    }

    private Set<Integer> getXvalues() {
        Set<Integer> xValues = new HashSet<>();
        for (Point point : getPoints()) {
            xValues.add(point.getX());
        }
        checkRectangle(xValues);
        return xValues;
    }

    private Set<Integer> getYvalues() {
        Set<Integer> yValues = new HashSet<>();
        for (Point point : getPoints()) {
            yValues.add(point.getY());
        }
        checkRectangle(yValues);
        return yValues;
    }

    private int calculateLength(Set<Integer> values) {
        List<Integer> vals = new ArrayList<>(values);
        return Math.abs(vals.get(0)-vals.get(1));
    }

    private void checkRectangle(Set<Integer> values) {
        if(values.size() != 2) {
            throw new IllegalArgumentException(NOT_RECTANGLE_ERROR);
        }
    }
}
profile
차곡차곡

0개의 댓글