Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발자 도전기

[JAVA] 상속 본문

개발공부/JAVA

[JAVA] 상속

jnnjnn 2024. 3. 7. 18:08

 

상속이란?

 

상속은 부모 클래스의 필드와 메소드를 자식 클래스에 물려주는 것을 말한다

 

상속은 왜 필요할까?

 

상속은 이미 잘 만들어진 클래스를 재사용해서 새로운 클래스를 만들기 때문에 중복되는 코드를 줄여줄 수 있다. 클래스 A, B가 있는데 클래스 A와 클래스 B와 코드가 중복되고 클래스 B가 A보다 조금 더 코드를 많이 가지고 있다면 클래스 A를 부모 클래스로 해서 클래스 A의 필드와 메소드를 자식클래스 B에게 상속하는 것이 효율적이다.

 

상속의 또다른 이점은 클래스의 수정을 최소화할 수 있다는 것이다. 부모 클래스를 수정하면 자식 필드들의 중복되는 코드들도 모두 수정되기 때문에 개발 시간을 단축시킬 수 있다.

 

클래스 상속

 

다음과 같이 자식 클래스에 상속받을 부모를 선언한다. 인터페이스와 달리 상속은 다중 상속을 허용하지 않는다.

public class 자식클래스 extends 부모클래스{
}

 

상속이 적용된 예제를 살펴보자

 

public class C01Inheritance {
    public static void main(String[] args) {
        C01Child child = new C01Child();
        child.name = "홍길동";
        System.out.println("child.name = " + child.name); // 홍길동
        child.method1();
    }
}

class C01Parent {
    public String name;
    public void method1() {
        System.out.println("C01Parent.method1");
    }
}

// extends : 부모의 멤버를 이 클래스에 상속함
class C01Child extends C01Parent {

}

 

Child 객체는 Parent 클래스의 필드와 메소드를 사용할 수 있다.

 

https://abc-datatype.tistory.com/79

 

[JAVA] 상속 - super 키워드

부모 생성자 호출 현실에서 부모 없는 자식이 있을 수 없듯이 자바에서도 자식 객체를 생성하면 부모 객체가 먼저 생성된 후에 자식 객체가 생성된다. 객체가 생성될 때 생성자를 호출해야 하기

abc-datatype.tistory.com

 

메소드 오버라이딩

부모 클래스의 메소드를 그대로 자식 클래스가 사용하기에 적합하지 않을 수 있다. 이러한 메소드는 자식 클래스에서 재정의해서 사용한다. 이것을 메소드 오버라이딩이라고 한다. 메소드가 오버라이딩되었다면 해당 부모 메소드는 숨겨지고, 자식 메소드가 우선적으로 사용된다.

 

메소드를 오버라이팅할 때는 다음과 같은 규칙에 주의해서 작성해야 한다

  • 부모 메소드의 선언부(리턴 타입, 메소드 이름, 매개변수)와 동일해야 한다
  • 접근 제한을 더 강하게 오버라이할 수 없다 ( public -> private ) 불가
  • 새로운 예외를 throws할 수 없다.
public class C01Override {
    public static void main(String[] args) {
        C01Animal animal = new C01Animal();
        animal.breathe(); // 호흡합니다
        C01GoldFish goldFish = new C01GoldFish();
        C01Cat cat = new C01Cat();
        goldFish.breathe(); // 아가미로 호흡합니다 (오버라이딩 된 메소드 호출)
        cat.breathe(); // 폐로 호흡합니다 (오버라이딩 된 메소드 호출)
    }
}

class C01Animal {
    public void breathe() {
        System.out.println("호흡합니다");
    }
}

class C01GoldFish extends C01Animal {
    // method override : 상위 타입의 메소드를 재정의
    public void breathe() {
        System.out.println("아가미로 호흡합니다");
    }

}

class C01Cat extends C01Animal {
    public void breathe() {
        System.out.println("폐로 호흡합니다");
    }

}

 

자바는 개발자의 실수를 줄여주기 위해 정확히 오버라이딩이 되었는지 체크해주는 @Override 어노테이션을 제공한다. @Override를 붙이면 컴파일 단계에서 정확히 오버라이딩이 되었는지 체크하고, 문제가 있다면 컴파일 에러를 출력한다.

 

추가로 인텔리제이에서는 Alt + Insert 단축키로 편리하게 메소드 오버라이딩을 추가할 수 있다.

 

 

자동 타입 변환

 

클래스 타입은 다른 클래스 타입으로 변환이 가능한데, 자동 타입 변환은 의미 그대로 자동적으로 타입 변환이 일어나는 것을 말한다. 자식은 부모의 특징과 기능을 상속받았기 때문에 자식타입객체는 부모타입으로 자동 타입 변환이 가능하다.

 

class Animal {
}

class Cat extends Animal{
}

public class Promotion {
    public static void main(String[] args) {
        Cat cat = new Cat();
        Animal animal = cat; // 자동타입변환
    }
}

 

이때 cat과 animal 변수는 각각 Cat 타입과 Animal 타입으로 다르지만 동일한 Cat 객체를 참조한다.

따라서 두 참조 변수의 == 연산 결과는 true가 나온다.

 

바로 위의 부모가 아니더라도 상속 계층에서 상위 타입이라면 자동 타입 변환이 일어날 수 있다.

class David extends Cat{
}

Animal A = new David(); // 가능
Cat B = new David(); // 가능

// David C = new Cat(); 불가능
// David D = new Animal(); 불가능

 

부모 타입으로 자동 변환된 이후에는 부모 클래스에 선언된 필드와 메소드로만 접근이 가능하다. 비록 변수는 자식 객체를 참조하지만 변수로 접근 가능한 멤버는 부모 클래스 멤버로 한정된다. 그러나 자식 클래스에서 오버라이딩된 메소드가 있다면 부모 메소드 대신 오버라이딩된 메소드가 호출된다.

 

public class C03Polymorphism {
    public static void main(String[] args) {
        C03Fish fish = new C03Fish();
        fish.breathe();
        fish.swim();

        C03Animal animal = fish;
        animal.breathe(); // 아가미 호흡
        // 참조변수의 타입이 가지고 있는 메소드만 사용 가능
        // animal.swim(); 불가능
    }
}

class C03Animal {
    public void breathe() {
        System.out.println("호흡하다");
    }
}

class C03Fish extends C03Animal {
    @Override
    public void breathe() {
        System.out.println("아가미 호흡");
    }

    public void swim() {
        System.out.println("헤엄치다");
    }
}

 

 

만약 자식 객체의 메소드를 사용하고 싶다면 다시 자식 타입으로 강제 타입 변환을 해주어야 한다.

 

 

강제 타입 변환 (Casting)

부모 타입으로 변환한 객체는 자식 객체의 메소드를 사용할 수 없다. 자식 객체의 메소드를 사용하려면 다시 자식 타입으로 강제 타입 변환을 해주어야 한다. 자식 타입은 부모 타입으로 자동변환되지만, 부모 타입은 자식 타입으로 자동 변환되지 않는다.

 

이 경우엔 캐스팅 연산자로 강제 타입 변환을 해야 한다. 자식 객체가 부모 타입으로 자동 변환된 경우에만 강제 타입 변환을 사용할 수 있다.

Parent parent = new Child(); // 자동 타입 변환
Child child = (Child) parent // 강제 타입 변환, 자식 메소드 사용 가능

 

 

 

https://abc-datatype.tistory.com/81

 

[JAVA] instanceof

어떤 객체가 해당 타입이 맞는지 확인할 때 사용하는 연산자이다. boolean result = 객체 instanceof 타입 좌항의 객체가 우항의 타입이면 true, 그렇지 않으면 false를 산출한다. 자바 12부터는 instanceof 연

abc-datatype.tistory.com

 

다형성

다형성이란 사용 방법은 동일하지만 실행 결과가 다양하게 나오는 성질을 말한다. 자동차의 부품을 교환하면 성능이 다르게 나오듯이 객체는 부품과 같아서, 프로그램을 구성하는 객체를 바꾸면 프로그램의 실행 성능이 다르게 나올 수 있다.

 

예를 들어 자동차는 동일한 타이어의 규격을 사용하지만 각 타이어가 어느 브랜드의 타이어인가에 따라 각 타이어의 성능은 다르게 나오는 것을 말한다.

 

객체의 사용 방법이 동일하다는 것은 동일한 메소드를 가지고 있고, 해당 메소드를 상속받았다는 뜻이다. 또한 성능이 다르게 나오는 것은 자식 클래스에서 해당 메소드를 오버라이딩(재정의) 했다는 뜻이다.

 

자동 타입 변환과 메소드 오버라이딩으로 다형성을 구현할 수 있다.

 

필드 다형성

필드 다형성은 필드 타입은 동일하지만 대입되는 객체가 달라져서 실행 결과가 다양하게 나올 수 있는 것을 말한다.

 

다음과 같이 Tire 클래스를 이용하는 Car 클래스가 있다고 하자

public class Car {

public Tire tire;

pulbic void run(){
	tire.roll();
	}
}

 

Car myCar = new Car();
myCar.tire = new HankookTire();
myCar.tire = new KumhoTire();

 

Car 클래스에 각각 다른 객체인 한국타이어와 금호타이어와를 대입하기 위해 부모 클래스인 Tire타입의 필드를 선언해주었다. Car 클래스의 run() 메소드는 tire 필드에 대입된 객체의 roll() 메소드를 호출한다. 만약 HankookTire와 KumhoTire가 roll() 메소드를 재정의하고 있다면, 재정의된 roll() 메소드가 호출된다.

 

따라서 어떤 타이어를 장착했는지에 따라 roll() 메소드의 실행 결과는 달라지게 된다. 이것이 바로 필드의 다형성이다.

 

 

매개변수 다형성

필드를 따로 선언할 필요 없이 매개변수에 넣어줄 수도 있다. 메소드가 클래스 타입의 매개변수를 가지고 있을 경우, 동일한 타입의 객체를 제공하는 게 정석이지만 자식 객체를 제공할 수도 있다. 자식 객체가 메소드를 오버라이딩하고 있다면 어떤 자식 객체가 제공되느냐에 따라서 실행 결과가 달라지므로 여기서 다형성이 발생한다.

 

public class Vehicle {
    public void run() {
        System.out.println("차량이 달립니다");
    }
}

public class Bus extends Vehicle {
    @Override
    public void run() {
        System.out.println("버스가 달립니다");
    }
}

public class Taxi extends Vehicle {
    @Override
    public void run() {
        System.out.println("택시가 달립니다");
    }
}

public class Driver {
    public void drive(Vehicle vehicle) {
        vehicle.run();
    }
}

public class DriverExample {
    public static void main(String[] args) {
        Driver driver = new Driver();
        driver.drive(new Bus()); // 버스가 달립니다
        driver.drive(new Taxi()); // 택시가 달립니다
    }
}

 

https://abc-datatype.tistory.com/78

 

[JAVA] 상속 - 추상 클래스

사전적 의미로 추상이란 실체 간의 공통되는 특성을 추출한 것을 말한다. 예를 들어 새, 곤충, 물고기 등의 공통점은 동물이다. 여기서 동물은 실체들의 공통된 특성을 가지고 있지만 실체가 아

abc-datatype.tistory.com

 

https://abc-datatype.tistory.com/80

 

[JAVA] 상속 - 클래스와 메소드의 final 키워드

final final이 붙으면 변경할 수 없다는 뜻이다. 변수에서의 final은 한 번 값을 할당하면 재할당할 수 없다, 클래스의 final 더 이상 상속할 수 없는 클래스가 된다 메소드의 final 오버라이딩 할 수 없

abc-datatype.tistory.com

 

 

추가로 봐야하는 내용들은 링크로 정리해두었다.

'개발공부 > JAVA' 카테고리의 다른 글

[JAVA] 상속 - super 키워드  (2) 2024.03.08
[JAVA] 상속 - 추상 클래스  (0) 2024.03.08
[JAVA] Getter와 Setter  (3) 2024.03.06
[JAVA] 접근 제한자(Access Modifier)  (0) 2024.03.06
[JAVA] static final(상수)  (0) 2024.03.06