cf) 메서드 오버로드 조건
- 메서드 이름 동일
- 매개변수갯수 다르거나, 순서 다르거나, 자료형이 다르다
※ 메서드 오버라이딩 조건
- 상속관계
- 메서드이름 동일, 매개변수 동일, 반환형 동일해야한다.
- 접근범위는 부모메서드 접근범위보다 <= 자식메서드 접근범위가 더 넓거나 같아야 한다.
class Parent { | class Child extends Parent{ |
void m(){ } | //void m(){ } //protected void m(){ } //public void m(){ } // OK |
} | //private void m(){ } // ERROR |
} |
abstract class Shape{ // 컴파일시 class Shape extends Object{} 로 바뀜.
// private double area;
protected double area;
double getArea() {
return area;
}
// void makeArea() {
//
// }
abstract void makeArea();
public String toString() {
return "도형의 면적은 " + area + "입니다";
}
}
class Triangle extends Shape{
// void makearea 하면 에러남
void makeArea() {
}
}
class Circle extends Shape { // shape로부터 확장된/상속받는 class이다. 자식 쪽에서 부모를 결정한다.
// 부모로부터 상속받으면 자식 class가 간결해짐. 재사용성이 높아짐.
private int radius;
Circle(int radius) {
this.radius = radius;
}
int getRadius() {
return radius;
}
void makeArea() {
area = 3.14 * radius * radius;
}
public String toString() {
return "반지름이 " + radius + "인 원 " + super.toString(); //super.toString 부모의 메소드 불러옴, 형제들 사이는 전혀 상관없다
}
}
class Rectangle extends Shape {
private int width, length;
Rectangle(int width, int length) {
this.width = width;
this.length = length;
}
void makeArea() {
area = width * length;
}
public String toString() {
return "가로 " + width + ", 세로 " + length + "인 사각형 " + super.toString();
}
}
/*
public class ShapeTest { //=public class ShapeTest extends Object{}
//실행시에 필요한 로드된 클래스 갯수 : public, object, string[], circle, system, rectangle 6개
public static void main(String[] args) {
Circle c = new Circle(5); // 반지름이 5인 원객체
System.out.println(c.getRadius()); //5
c.makeArea(); //원의 면적을 계산한다.
System.out.println(c.getArea()); //면적값 X.XXXX
Rectangle r = new Rectangle(3, 4); //가로3, 세로4인 사각형객체
r.makeArea(); // 사각형의 면적을 계산한다
System.out.println(r.getArea()); // 면적값 12.0
}
}
*/
/*
public class ShapeTest {
public static void main(String[] args) {
Shape[] shapes = new Shape[5];
shapes[0] = new Circle(5); //upcasting
shapes[1] = new Rectangle(3, 4); //upcasting
for(int i = 0; i<2; i++) {
// shapes[i].makeArea(); 이게 불가능해서 아래처럼 downcasting(자식타입으로 강제형변환)
// Rectangle 객체도 있어서 instanceof 안하고 그냥 이렇게만 쓰면
// ClassCastException 발생함
// Circle c = (Circle)shapes[i];
// c.makeArea();
// System.out.println(c.getArea());
// 무조건 downcasting 할 수 있는거 X
if(shapes[i] instanceof Circle) { // downcasting전에 꼭 물어보기
//instanceof 원래 객체가 Circle type 객체니?
Circle c = (Circle)shapes[i];
c.makeArea();
System.out.println(c.getArea());
}else if(shapes[i] instanceof Rectangle) {
Rectangle r = (Rectangle)shapes[i];
r.makeArea();
System.out.println(r.getArea());
}
}
}
}
*/
// 사용자코드
// 부모에 메서드만 있으면 재정의되서 위에 처럼 객체 확인
// 강제형변환 안하고 아래처럼 간단하게 작성 가능
public class ShapeTest {
public static void main(String[] args) {
Shape[] shapes = new Shape[5]; // 방을 생성한거지 Shape 객체를 생성한건 아님.
shapes[0] = new Circle(5); //upcasting
shapes[1] = new Rectangle(3, 4); //upcasting
System.out.println(shapes[4]); //shapes[4].toString()가 자동 호출 null
for(int i = 0; i<2; i++) {
shapes[i].makeArea();
System.out.println(shapes[i].getArea());
System.out.println(shapes[i].toString()); // Circle@200a570f, Rectangle@16b3fc9e
System.out.println(shapes[i]); //shapes[i].toString()가 자동 호출됨
//= System.out.println(shapes[i]); 알아서 인자의 toString 메서드가 자동 호출, shapes[i].toString()
// Shape class에 빈 makeArea 만들었음, shape class에 makeArea 있는지 컴파일 시 확인하고 실행됨
// 실행할 때는 그 shape로 부터 상속받은 실제 객체 circle/rectangle에 오버라이딩된 메서드 호출된다.
// 0번 인덱스가 참조하는 객체 Circle 타입, 1번 인덱스 Rectangle
// 0번 인덱스 자료형이 shape 타입이니까 부모인 shape 영역만 참조 가능, 자식영역에서 makeArea가 재정의되서 덮어쓰기
// 오버라이딩 된 거 메서드는 계속 유지되서 사용됨
// 인덱스에 따라 makeArea 각자꺼 가져와서 사용, 이게 다형성
// 도형의 면적은 78.5입니다. //도형의 면적은 12.0입니다가 나오도록 toString을 오버라이딩필요, 이 경우 부모가 object, 자식이 shape가 됨.
/* shape에 이거 넣으면 됨.
public String toString() {
return "도형의 면적은 " + area + "입니다";
}
*/
// 반지름이 5인 원 도형의 면적은 78.5입니다. //가로3, 세로4인 사각형 도형의 면적은 12.0입니다가 나오도록 Circle과 Rectangle에 오버라이딩
}
}
}
※ System.out.println(shapes[i]); 이건 아래 10개 중 9째인 부모인 Object type의 매개변수 있는게 출력됨
PrintStream.println(), PrintStream.println(boolean), PrintStream.println(char), PrintStream.println(char[]), PrintStream.println(double), PrintStream.println(float), PrintStream.println(int), PrintStream.println(long), PrintStream.println(java.lang.Object), PrintStream.println(java.lang.String)
↓
public void println(Object x) {
String.valueOf(x);
}
↓
public static String valueOf(Object obj) {
if(obj == null) {
return "null";
else {
return obj.toString.toString();
}
}
shapes[0].mc();
shapes[1].mr();
→ compile 에러 남. shpaes 클래스에 mc,mr메서드가 없기 때문
쓰고 싶으면
Circle c = (Circle)shapes[0];
c.mc();
이런식으로 downcasting 해야함
m(); void 만들어두면 알아서 오버라이딩된 메서드 호출됨
shapes[0].m();
shapes[1].m();
까다롭지만 오버라이딩 안하면 사용자가 쓰기 불편하다. 재사용성이 떨어진다
'언어 > Java' 카테고리의 다른 글
이클립스 Source로 메서드 작성하기 (0) | 2023.08.01 |
---|---|
상속과 생성자 (0) | 2023.08.01 |
업캐스팅(Upcasting), 다운캐스팅(Downcasting) (0) | 2023.08.01 |
오버라이딩(Overriding)과 다형성(Polymorphism) (0) | 2023.07.31 |
상속 예제 (0) | 2023.07.31 |