Contents
접기
다형성
하나의 객체가 여러 가지 타입을 가질 수 있는 것
Parents (세 도형의 공통점)
점(MyPoint) | |
- x : int //private - y : int + toString() : String // public + calcArea(): double |
생성자, 세터게터 필요 상속받으면 반드시 면적을 계산 ==> abstract로 |
Child
원(MyCircle) extends MyPoint | 삼각형(MyTriangle) extends MyPoint | 사각형(MyRectangle) extends MyPoint |
- radius : double // 원에만 + toString() : String + calcArea() : double |
- width : double - height : double + toString() : String + calcArea() : double |
- width : double - height : double + toString() : String + calcArea() : double |
MyPoint
package shape.vo;
public abstract class MyPoint {
private int x;
private int y;
public MyPoint() {
super();
}
public MyPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
// 일반 메소드 = 면적을 구하는 메소드
public abstract double calcArea();
@Override
public String toString() {
return "x=" + x + ", y=" + y ;
}
}
코드 | 의미 |
public abstract double calcArea(); | 일반 메소드 = 면적을 구하는 메소드 |
MyCircle
package shape.vo;
public class MyCircle extends MyPoint {
private double radius;
// 생성자
public MyCircle() {
super();
}
public MyCircle(double radius) {
super();
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double calcArea() {
return this.radius * this.radius * Math.PI;
} // 원의 면적
@Override
public String toString() {
return super.toString()+ // 부모의 toString()
", radius = " + radius + ", area = " + calcArea();
}
}
main (하나씩 만들면서 확인해 보기)
package shape.main;
import shape.vo.MyCircle;
public class ShapeMain {
public static void main(String[] args) {
//Circle 만들고 확인
MyCircle c = new MyCircle(5);
System.out.println(c);
c.setX(4);
c.setY(3);
System.out.println(c);
}
}
x=0, y=0, radius = 5.0, area = 78.53981633974483
x=4, y=3, radius = 5.0, area = 78.53981633974483
MyRectangle
package shape.vo;
public class MyRectangle extends MyPoint {
private double width;
private double height;
public MyRectangle() {
super();
}
public MyRectangle(double width, double height) {
super();
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public void setWidth(double width) {
this.width = width;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public double calcArea() {
return width * height;
}
@Override
public String toString() {
return super.toString() + ", width = " + width + ", height = " + height + ", area = " + calcArea();
}
}
MyTriangle
package shape.vo;
public class MyTriangle extends MyPoint {
private double width;
private double height;
public MyTriangle() {
super();
}
public MyTriangle(double width, double height) {
super();
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public void setWidth(double width) {
this.width = width;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public double calcArea() {
return width * height * 0.5;
}
@Override
public String toString() {
return super.toString() +", width = " + width + ", height = " + height + ", area = " + calcArea() ;
}
}
다형성 예시
MyPoint 에 임시 메소드(temp)를 넣음
// 다형성 테스트
// 임시메소드
public void temp() {
System.out.println("포인트 클래스입니다~");
}
MyCircle
// 다형성 테스트
// 임시메소드
@Override
public void temp() {
System.out.println("원 클래스입니다~");
}
Main
하게 되면 원 클래스의 temp 안에 속한 출력문이 나온다.
package shape.main;
import shape.vo.MyCircle;
import shape.vo.MyPoint;
import shape.vo.MyRectangle;
import shape.vo.MyTriangle;
public class ShapeMain {
public static void main(String[] args) {
MyPoint p = new MyCircle();
p.temp();
System.out.println(p);
다형성 특징
1. 부모의 레퍼런스 변수가 자식 객체의 위치값을 갖도록 한다.
- MyPoint 는 객체를 생성할 수 없다.
-> ? abstract 이니까 p = MyPoint 라고 생각하지만 사실은 MyCircle 인 것 = 다형성
- 오버라이드와는 무슨 연관?
각자 같은 이름의 메소드가 존재
-> 포인트는 C 안에 MyPoint Temp를 가리킨다 생각하지만 사실은 MyCircle 의 temp를 가리키는 것이다.
System.out.println(p); = p.toString()과 같다 -> 원에 대한 출력문이 나오게 된다.
오버라이드를 하지 않은 클래스에서 temp를 부른다면?
p = new MyRectangle();
p.temp();
System.out.println(p);
포인트 클래스입니다~
x=0, y=0, width = 0.0, height = 0.0, area = 0.0
MyPoint 클래스에서 만들어진 temp 메소드 출력문이 나오게 된다.
=> 상속이 되어야만 다형성 가능하다.
2. 캐스팅
타입 변환 = 형 변환
MyPoint p = new MyCircle(); // 부모가 자식객체를
// 다운캐스팅 (부모타입을 자식으로 변환)
MyCircle tt = new MyCircle();
// MyPoint 로 업캐스팅(자식을 부모로 변환)
MyPoint tmp = ((MyPoint)tt);
// MyCircle -> MyPoint로
((MyPoint)p).temp(); // p를 캐스팅 후에 불러옴.
업 캐스팅 | 다운 캐스팅 |
MyPoint tmp = ((MyPoint)tt); | MyPoint p = new MyCircle(); |
자식 클래스가 부모 클래스 타입으로 캐스팅 되는 것. | 부모 클래스가 자식 클래스 타입으로 캐스팅 되는 것. |
instanceof 연산자
실제 가리키는 타입이 맞는지 확인하는 연산
형태 : 변수 instanceof 타입
Object obj = new Object();
System.out.println(p instanceof MyPoint); // true // x
// 실제 가리키는 타입이 맞는지 확인하는 연산자
System.out.println(p instanceof MyCircle); // true // ** 많이 사용
// 선언된 것도 맞지만 실제로 가리키는 것도 같이 확인 한다.
System.out.println(tt instanceof MyCircle); // true // x
// 상속관계가 맞으면 무조건 true
// System.out.println(tt instanceof MyRectangle); // 오류
// 상속관계가 아니닌ㄲㅏ!
System.out.println(obj instanceof MyPoint); // false
// 부모는 자식을 .. 확인하지는 못 한다.
// 잘 안씀 오직 예제
코드 | 의미 |
1) System.out.println(p instanceof MyPoint); | true |
2) System.out.println(p instanceof MyCircle); | true 선언된 것도 맞지만 실제로 가리키는 것도 같이 확인 한다. |
3) System.out.println(tt instanceof MyCircle); | true 상속관계가 맞으면 무조건 true |
4) System.out.println(obj instanceof MyPoint); | false 부모는 자식을 .. 확인하지는 못 한다. |
5) System.out.println(tt instanceof MyRectangle); | 연관되지 않은 클래스와는 오류가 난다. |
가장 많이 사용하는 예제는 2) 번이며 나머지 출력문은 오직 확인을 위한 예제 출력문이다. (잘 사용하지 않음)
eclips에서 클래스 생성시 상속 (extends ..) 바로 만드는 방법!
'국비 교육 > 백엔드(Java, Spring)' 카테고리의 다른 글
[자바] 자바 주요 API - String (0) | 2024.01.29 |
---|---|
[자바] ArrayList, HashSet, HashMap (0) | 2024.01.29 |
[자바] 상속, 오버라이딩, 추상화 클래스 예제 - 입장권 판매 (0) | 2024.01.25 |
[자바] 상속(Inheritance), 오버라이딩(Overriding), 추상화 클래스 (Abstract Class) (0) | 2024.01.25 |