[JAVA] 상속, 오버라이딩, 객체 클래스, 추상 클래스

HYEOB KIM·2022년 8월 12일
1

JAVA

목록 보기
9/9

상속이란?

상위 객체(부모 클래스)의 필드와 메소드를 물려받아 재사용하는 것입니다.
이미 개발된 객체를 재사용하여 개발하므로 코드의 중복을 줄일 수 있어 효율적인 개발이 가능합니다.

부모 클래스자식 클래스
돈, 자동차, 집돈, 자동차, 집, 컴퓨터
공부한다(), TV를 본다()공부한다(), TV를 본다(), 게임을 한다()

IS-A 관계

하위 클래스 is a 상위 클래스가 참인 경우

  • 여러 클래스에서 공통된 부분이 있으면 항상 상위 클래스를 뽑아내 상속을 하면 될까요?
  • is-a 관계가 성립할 때에만 상속 관계를 맺어주라고 합니다.

상속의 표현

자식 클래스 선언 시 extends 키워드를 이용하여 부모 클래스를 상속 받습니다.

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

public class Student extends Person { }
public class Teacher extends Person { }
public class Staff extends Person { }

HAS-A 관계

  • is-a 관계 외에 has-a 관계도 상속으로 표현이 가능합니다.
  • 하지만 has-a 관계는 상속보다 포함관계를 유지하는 것이 보다 일반적입니다. 예를 들어, employee 클래스 안에 필드값으로 department 클래스를 가지고 있을 경우 has-a 관계이자 포함관계입니다.

예제

Animal.java

public class Animal {
	private int age;
	private String kind;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getKind() {
		return kind;
	}
	public void setKind(String kind) {
		this.kind = kind;
	}
	
	public void run() {
		System.out.println("달려라!!!");
	}
}

Cat.java

public class Cat extends Animal{
	private String name;
	
	public String getName() {
		return this.name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void hunt() {
		System.out.println("쥐를 잡을꺼야!!");
	}
	
	public void play() {
		System.out.println("모빌 놀이가 좋아요~");
	}
}

AnimalTest

public class AnimalTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Cat cat = new Cat();
		
		cat.setName("야옹이");
		cat.setAge(3);
		cat.setKind("페르시안");
		
		System.out.println("이름 : " + cat.getName());
		System.out.println("나이 : " + cat.getAge() + "살");
		System.out.println("종류 : " + cat.getKind());
		cat.run();
		cat.hunt();
		cat.play();
	}
}

Cat의 부모 클래스는 Animal입니다.
따라서 AnimalTest에서 Cat에 적혀있지 않은 필드값과 메소드를 사용 가능한 모습을 볼 수 있습니다.

상속에서의 생성자

  • 생성자는 객체 생성 시, 자신의 클래스에 대한 객체만 생성합니다.

  • 자식 클래스에서는 부모의 필드나 멤버 메소드를 사용해야 하기 때문에 부모의 생성자를 호출하여 부모의 객체를 먼저 만들어주어야 합니다.

  • super() 키워드를 이용하여 부모의 생성자를 호출합니다.

  • 명시적으로 부모의 생성자를 호출하지 않는 경우, 자동으로 super()가 추가됩니다.

  • super() 키워드는 반드시 생성자의 첫 번째 줄에 기술되어야 합니다.

  • super()this()를 같이 호출할 수 없습니다.

예제

public class Person {
    public Person() {

    }

    public Person(String name, String phoneNumber) {
        this.name = name;
        this.phoneNumber = phoneNumber;
    }
}
public class Student extends Person {
	private String department;
    public Student(String department) {
    	super(); // 기본 생성자와 연결, 부모 클래스에 기본 생성자가 정의되어 있어야 합니다.
        this.department = department;
    }
    
    public Student(String name, String phoneNumber) {
    	super(name, phoneNumber);
    }    
}

오버라이딩(Overriding)

자식 클래스에서 부모 클래스의 메소드를 재정의하는 것을 말합니다.

public class Parent {
  private String name;
  private String job;
  
  public void eat() {}
  
  public void doAfterEat() {
    System.out.println(“커피를 마십니다.);
  }
}

// Parent 클래스를 상속받은 Child 클래스
public class Child extends Parent{
  public void doAfterEat() {
  	System.out.println(“양치를 합니다.);
  }
}

조건

  • 메소드 이름 같아야 합니다.
  • 메소드 파라미터의 개수와 데이터 타입이 같아야 합니다.
  • 메소드의 리턴 타입이 같아야 합니다.
  • 접근제어자는 부모의 것과 같거나 더 넓은 범위여야 합니다.

부모 클래스의 메소드 사용 방법

자식 클래스에서 부모 클래스의 메소드를 사용하고 싶다면 메소드 앞에 super.를 붙여서 사용합니다.

public class Child extends Parent {
	public void doEatAfter() {
    	super.doEatAfter();  // 부모 클래스의 메소드 doEatAfter()를 사용하는 방법
        System.out.println("양치를 합니다.");
    }
}

final 키워드

  • final 클래스 : 자식 클래스를 만들 수 없습니다.
public final class ClassA { }
  • final 메소드 : 자식 클래스에서 오버라이딩 할 수 없습니다.
public class ParentClass {
	public final void methodA() { }
}
  • final 변수 : 값을 변경할 수 없습니다.
final int age = 24;

Annotation

  • @Override : 해당 메소드가 부모 클래스의 메소드를 오버라이딩 한 메소드라는 것을 나타냅니다. 만약 어노테이션을 사용한 메소드가 오버라이딩 된 메소드가 아닌 경우, 컴파일러가 에러를 발생시킵니다.
public class Student extends Person {
	private String department;
    
    @Override
    public void study() {
    	System.out.println("공부합니다.");
    }
    
    @Override
    public void eat() {
    	super.eat();
    }
}

Object Class

  • 자바의 최상위 부모 클래스
  • extends 키워드로 다른 클래스를 상속하지 않은 클래스는 암시적으로 Object 클래스를 상속하게 됩니다.
  • 필드가 없고, 메소드만으로 구성되어 있습니다.
  • toString()과 같은 유용한 메소드를 제공합니다.
public class PersonObj {
	private String name;
    private String phoneNumber;
    
    public PersonObj(String name, String phoneNumber){
    	this.name = name
        this.phoneNumber = phoneNumber;
    }
    
    @Override
    public String toString(){   // 최상위 부모 클래스인 Object의 메소드 중 하나인 toString()
    	return "이름 : " + name + ", 전화번호 : " + phoneNumber;
    }
}

public class PersonObjTest {
	public static void main(String[] args) {
    	PersonObj person = new PersonObj("홍길동", "111-5555-9999");
    }
    
    // 단순히 변수명을 출력하면 클래스의 toString() 메소드에 정의된 리턴 값이 나타납니다.
    System.out.println(person);
}

추상 클래스

클래스들의 공통적인 특성을 추출하여 선언한 클래스입니다.
객체를 직접 생성하여 사용할 수 없습니다(미완성 설계도).

  • 추상 클래스를 사용하는 목적은 상속 받는 자식 클래스들에게 개발 규격을 통일시키고 강제하기 위함입니다.
  • 꼭 사용해야 할 필요는 없지만, 규격화 시키는 목적으로 사용합니다.
Appliance app = new Radio(); // Appliance는 추상 클래스

추상 메소드

메소드 body가 없는 메소드

public abstract void openAccount();

추상 클래스에서만 선언 가능합니다.
일반 필드, 생성자, 메소드 선언이 가능합니다.

profile
Devops Engineer

0개의 댓글