[JAVA] 상속

코박·2022년 3월 25일
0

JAVA

목록 보기
1/4
post-thumbnail

1. 자바 상속의 특징

(1) 상속(Inheritance)

자식(class)이 상속받고 싶은 부모(class)를 선택해서 물려받음

이때 상속받는 클래스를 자식 클래스, 하위 클래스 또는 서브 클래스

상속을 해주는 클래스를 부모 클래스, 상위 클래스 또는 슈퍼 클래스

(2) 상속의 특징

상속의 장점은 처음에 설명했던 것과 큰 차이가 없음

중복된 코드를 줄일 수 있고, 유지 보수가 편리하며, 통일성이 있고 다형성을 구현

(3) 선언

자식 클래스가 여러 부모로부터 다중 상속을 받는 것은 불가능

즉, 1개의 부모 클래스로부터의 단일 상속만 허용

하지만 부모 클래스는 여러 개의 자식 클래스에게 상속이 가능

자식 클래스로 인스턴스를 생성하는 것이 효율적

2. super 키워드

(1) Super()

부모 클래스 객체를 즉시 참조할 때 사용하는 참조변수

서브클래스의 인스턴스를 만들 때, 부모 클래스의 인스턴스는 내재적으로 만들어짐

(2) 사용법

1) 부모 클래스 인스턴스 변수를 즉시 참조시 사용

슈퍼 키워드가 없을 경우 문제 발생

2) super()는 부모 클래스 생성자를 즉시 호출 할 때 사용

컴파일러에 의해 super()는 자동으로 각 클래스 생성자에 추가

3) super는 부모 클래스 메소드를 호출할 때 사용 될 수 있음

class Parent {
    int a;
    Parent(int n) { a = n; }
}

class Child extends Parent {
    int b;
    Child() {
        super();
        b = 20;
    }

3. 메소드 오버라이딩

(1) 정의

자식 클래스가 자신의 슈퍼클래스들 또는 부모 클래스들 중 하나에 의해 이미 제공된 메소드를 특정한 형태로 구현하는 것을 제공하는 언어의 특징

(2) 조건

1) 오버라이딩이란 메소드의 동작만을 재정의하는 것이므로, 메소드의 선언부는 기존 메소드와 완전히 동일

하지만 메소드의 반환 타입은 부모 클래스의 반환 타입으로 타입 변환할 수 있는 타입이라면 변경가능

2) 부모 클래스의 메소드보다 접근 제어자를 더 좁은 범위로 변경할 수 없음

3) 부모 클래스의 메소드보다 더 큰 범위의 예외를 선언할 수 없음

(3) 오버로딩과 오버라이딩

오버로딩 : 새로운 메소드 정의

오버라이딩 : 상속받은 기존의 메소드를 재정의

4. 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)

(1) 메소드 디스패치

어떤 메서드를 호출할지 결정하여 실제로 실행시키는 과정

컴파일 시에는 생성할 객체 타입에 대한 정보만 보유

(2) 스태틱 디스패치

컴파일 시점에서, 컴파일러가 특정 메소드를 호출할 것이라고 명확하게 알고있는 경우 (정적)

(3) 다이나믹 디스패치

정적 디스패치와 반대로 컴파일러가 어떤 메서드를 호출하는지 모르는 경우 동적 디스패치는 호출할 메서드를 런타임 시점에서 결정

(4) 더블 디스패치:

Dynamic Dispatch 를 두 번 하는 것을 의미

Dynamic Dispatch 를 두 번 하는 것을 의미

더블 디스패치는 방문자 패턴과 밀접한 관계

5. 추상 클래스

(1) 정의

각 클래스들 간에 비슷한 필드와 메소드를 공통적으로 추출해 만들어진 클래스

(2) 특징

클래스의 공통적인 부분을 추출해 어느정도 규격을 잡아놓은 추상적인 클래스

메서드와 내용이 추상적이기 때문에 객체를 생성할 수 없게 만들어짐

추상 클래스와 실체 클래스는 상속관계

(3) 사용 목적

1) 공통된 필드와 메소드를 통일할 목적

2) 실체 클래스 구현 시, 시간 절약

3) 규격에 맞는 실체클래스 구현

(4) 문법

package ABSTRACTCLASS;

public class Dog extends Animal{
	public Dog(){
		this.kind = "포유류";
	}
	
	@Override
	public void sound() {
		// TODO Auto-generated method stub
		System.out.println("왈왈!");
	}
}

Animal이라는 추상클래스를 구현, Animal 클래스 앞에 abstract 키워드가 있기 때문에 해당 클래스는 추상클래스임을 알 수 있음

추상클래스를 상속받는 실체 클래스들은 반드시 sound()라는 추상메서드를 상속받아 재정의(오버라이딩)해야함

package ABSTRACTCLASS;

public class Cat extends Animal{
	public Cat(){
		this.kind = "포유류";
	}
	@Override
	public void sound() {
		// TODO Auto-generated method stub
		System.out.println("야~옹!");
	}
}

Dog 실체클래스와 같음, 다만 sound() 추상메서드는 Cat실체클래스에 맞게끔 자기스타일대로 구현되어있음을 확인할 수 있음

여기서 오버라이딩을 하면, 다형성이 발생된다는 사실 확인 가능

6. final 키워드

(1) final 특징

변수(variable), 메서드(method), 또는 클래스(class)에 사용

final 키워드를 붙이면 무언가를 제한한다는 의미

1) 변수에 final을 붙이면 이 변수는 수정할 수 없다는 의미
public void variableFinal() {

  final int value = 2;
  final int value_2;

  System.out.println("value = " + value);

  value_2 = 3;
  System.out.println("person_2 = " + value_2);
}
2) 메서드에 final을 붙이면 override를 제한
public class Human{
	public int Age;
    public final void setAge(int _age)
    {
    	Age = _age;
    }
}
public class Student extends Human{
	public final void setAge(int age){ << 에러
    }
}
3) final 키워드를 클래스에 붙이면 상속 불가능 클래스
public final class Integer extends Number{

}

class IntegerV2 extends Integer << 에러

7. Object 클래스

(1) object 특징

자바에서 제공하는 클래스 중 하나

java.lang 패키지는 컴파일러에 의해 자동 import

(2) 종류

1) toString()

- 기본 동작: 객체의 해시코드 출력
- override 목적: 객체의 정보를 문자열 형태로 표현하고자 할 때
String str = new String("Apple");
System.out.println(str);

2) equals()

- 기본 동작: '==' 연산 결과 반환
- override 목적: 물리적으로 다른 메모리에 위치하는 객체여도 논리적으로 동일함을 구현하기 위해
public class User {

    int id;
    String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
    public static void main(String[] args) {
        User user1 = new User(1001, "홍길동");
        User user2 = new User(1001, "홍길동");
 
        System.out.println(user1.equals(user2));
    }
}
//결과는  false
서로 다른 인스턴스를 가리키는 참조변수를 equals()로 비교시 false

3) hashCode()

- 기본 동작: JVM이 부여한 코드값. 인스턴스가 저장된 가상머신의 주소를 10진수로 반환
- override 목적: 두 개의 서로 다른 메모리에 위치한 객체가 동일성을 갖기 위해
public class User {

    int id;
    String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    @Override
    public boolean equals(Object obj) {

        if (obj instanceof User) {
            return this.getId() == ((User)obj).getId();
        } else {
            return false;
        }
    }

    public static void main(String[] args) {

        User user1 = new User(1001, "홍길동");
        User user2 = new User(1001, "홍길동");

        System.out.println("user1.equals(user2): " + user1.equals(user2));
        System.out.println("user1.hashCode(): " + user1.hashCode());
        System.out.println("user2.hashCode(): " + user2.hashCode());
    }
}
User객체 user1과 user2가 서로 다른 해시코드 반환
자바의 Integer클래스도 Object클래스의 hashCode()를 Override 하고 있음
Integer i1 = 100;
Integer i2 = 100;

System.out.println("i1.hashCode(): " + i1.hashCode());
System.out.println("i2.hashCode(): " + i2.hashCode());
< 실행결과 >
i1.hashCode(): 100
i2.hashCode(): 100
profile
웹 개발자 할래요

0개의 댓글