개발 공부/JAVA

상속 (형변환/다형성/overriding)

공부하는개발자_ 2023. 5. 30. 08:59

객체 모델링을 먼저 해야한다. 개발 중에 새로운 모델링이 요구되면 기존 상속?이 바껴야한다. 

같은 클래스의 이름이어도 다른 패키지에 저장되면 다른 클래스로 인식함.

 

상속 (부모-자식)
공통점이 있으면 부모클래스로 도출함. 
부모의 변수와 메소드를 자식이 갖고 있는것처럼 사용할 수 있다
상위클래스의 멤버변수와 메서드는 하위클래스에 상속됨
자식이 구현해야할 코드가 줄어든다. 

부모클래스를 여러개 둘 수 없다. (단일 상속) 
IS A (KIND OF)관계에서만 성립 가능.

 

this: 현재 사용하는 객체

super: 현재 사용하는 객체의 부모 영역. this처럼 메서드 내에서 사용가능. 

변수                  선언위치            메모리영역             초기화시점

지역변수           메소드내부             stack                       자동초기화 안됨

매개변수           메소드내부             stack                       자동초기화 안됨

멤버변수           클래스내부

    인스턴스변수                               heap                       객체생성시 자동초기화 됨

     스테틱변수                                 method                   클래스로드시 자동초기화 됨

 

 

java.lang.Object : 최상위 클래스

hashCode() : 객체 정보 값

Child1은 Object의 변수, 메소드들을 갖게 됨.

h1과 h2의 결과 값은 다르다

 

Method Overriding

부모 클래스의 메소드가 자식 클래스가 사용하기에 적합하지 않을경우, 상속된 메소드를 자식 클래스에서 재정의 하는 것.


ex)

class A{

   private int i;

   A(int i){ this. i = i; }

   public String toString( ){

       return ""+ i;

   }

}

System.out.println(new A(5));   //A@XXXXXX대신 5 출력 

   --> void println(Object obj){

     --> String의 valueOf(Object x) {

        -->  x.toString( )호출됨 

 

 

오버라이딩 규칙

1) 상속관계의 메소드

2) 메소드 이름, 매개변수 (갯수, 자료형, 순서), 반환형이 같아야 한다
3) 하위 클래스 메소드 접근 범위 >= 상위 클래스 메소드 접근 범위

     -         public                                            public

     -         public, default                               default

     -         public, default, private                  private

 

ex) public class Object { //최상위 클래스

          public String toString( ){ }

}

class A{

      private String toString(){}   (X)

}

 

 

오버라이딩을 해야 하는 이유
다형성 구현
기능의 재정의
프로그램의 확장성
유지 보수와 코드 가독성
다양한 동작 구현

 

다형성

전달되는 인자에 따라 여러 형태로 사용할 수 있다.
다형성을 표현하려면 오버라이딩 되어있어야 한다.

초록색,빨간색 : object equals 메소드 호출 
파란색: string equals 메소드 호출  

 

자동타입변환

upcasting : 자식 타입->부모 타입으로 자동형변환

downcasting : 부모타입으로 upcasting된것만 downcasting가능.

upcasting, downcastiong과 관계없이 같은 메소드 호출되게 하려면 오버라이딩 해야한다.

(객체 생성 당시의 오버라이딩 된 메소드가 계속 유지 됨)

 

강제타입변환

부모타입 ->자식 타입 : ()안에 형변환

 

 

class Shape{

 

double area;

void make() {

 

}

void print() {

System.out.println("면적은"+area);

}

 

public String toString() {

return "도형의 면적:" + area;

}

 

}

 

 

 

class Circle extends Shape{

int radius;

Circle(int radius){

this.radius = radius;

}

public void make(){

area = radius*radius*Math.PI;

}

public void print() {

System.out.println("반지름이"+radius+"인 원의 ");

super.print();

}

public String toString() {

return "원" + super.toString();

}

}

 

 

class Rectangle extends Shape{

int width;

int height;

 

Rectangle(int width, int height){

this.width = width;

this.height = height;

}

 

public void make() {

area = width * height;

}

 

public void print() {

System.out.println("가로"+width+", 세로"+height+"인 사각형의");

super.print();

}

}

 

 

class Triangle{}

 

 

public class OverrideTest {

 

static void test(Shape s) {

s.make();

s.print();

System.out.println(s);//s.toString()메서드 호출됨

//Circle@xxxx

//도형의 면적:~

}

 

public static void main(String[] args) {

Circle c;

Rectangle r;

//Triangle t;

c = new Circle(5);// 반지름이 5인 원객체

//c.mc();

//c.print();

test(c);

 

r = new Rectangle(3,4);

//r.mr();

//r.print();

test(r);

 

//t = new Triangle(5,6);

//t.mt();

//t.print();

 

 

}

}