본문 바로가기

Java

Java(12) - 상속, 메서드 오버라이딩

728x90
반응형

<목차>

1) 상속, 메서드 오버라이딩

   1-1) 상속

   1-2) 메서드 오버라이딩

   1-3) 예제 풀이

 

 

 

 

1) 상속, 메서드 오버라이딩

1-1) 상속

개념

- 객체의 필드와 메서드를 다른 객체가 물려받을 수 있는 기능

- Is a Relationship

 

 

부모 클래스(super class) / 자식 클래스(sub class)

자식 클래스와 부모 클래스가 동일한 멤버 변수나 맴버 메서드를 사용한다고 하면

자식 클래스가 부모 클래스의 멤버 변수와 메서드를 그대로 물려받아 사용하는 것이

효과적이기 때문에 상속을 통해 이를 가능하게 한다고 보면 된다!

 

 

상속의 장점

- 기존의 클래스를 사용함으로써 재사용성을 높이고, 코드의 중복을 줄여 코드가 간결해짐

- 부모 클래스를 상속받는 여러 개의 자식 클래스에서 사용 가능하므로 확장성이 용이함

 

 

상속의 주의할 점

- 여러 개의 클래스를 상속할 수 없음(단 하나의 클래스만 부모 클래스로 설정 가능)

- private 접근 제한을 갖는 변수나 메서드는 상속이 불가능함

 

 

 

1-2) 메서드 오버라이딩

오버라이딩(Overriding)

- 개념 : 상위 클래스가 가지고 있는 메서드를 상속 관계의 하위 클래스의 메서드에서 재정의하여 사용하는 것

- Java에서 자식 클래스는 부모 클래스의 private 멤버를 제외한 모든 메서드를 상속받는데,

이렇게 상속받은 메서드는 그대로 사용해도 되고, 필요한 동작을 위해 재정의하여 사용할 수도 있다.

 

 

오버라이딩 조건

  1. 부모 - 자식(즉, 상속)관계에만 성립함
  2. 파라미터 개수, 타입 & 리턴 타입이 일치함
  3. 접근 지정자는 부모 <= 자식

 

(추가 기억 Popint) 생성자는 인스턴스를 만들기 위한 최소 조건이다!

 

 

 

 

1-3) 예제 풀이

패키지 chapter09.inheritance

Inheritance.class

package chapter09.inheritance;

class Human {    // 클래스
	int age;     // 멤버 변수
	String name;
	
	Human(int age, String name) {
		System.out.println("== Human 생성자 ==");
		this.age = age;
		this.name = name;
	}
	
	void intro() {   // 멤버 메서드
		System.out.println("안녕, " + age + "살 " + name + "이야");
	}
}

class Student extends Human {     // 상속 예약어 extends
	int stNum;
	String major;
	
	// 명시적 생성자 : 초기값을 가지고 있음
	Student(int age, String name, int stNum, String major) {
		super(age, name);    // super() : 부모-자식 관계에서 부모 클래스를 호출하는 예약어 --> 지금의 경우에는 age, name의 두 매개변수가 인수를 각각 받아서 Human 클래스의 명시적 생성자(age와 name을 매개변수로 가진 Human 생성자)를 호출하여 그 안의 코드를 수행시킴!!
		this.stNum = stNum;
		this.major = major;
	}
	
	void study() {
		System.out.println("스터디 스터디");
	}
	
}

public class Inheritance {

	public static void main(String[] args) {
		Human kim = new Human(29, "김상혁");
		kim.intro();
		
		Student lee = new Student(42, "이승우", 9312345, "경영");  // 명시적 생성자인 Student를 호출함!!
		lee.intro();     // Human 클래스가 가지고 있는 메서드를 상속받았기 때문에 Human 클래스의 intro() 메서드를 호출할 수 있음!!
		lee.study();

	}

}

 

 

 

 

Super.class

package chapter09.inheritance;

import java.time.LocalDate;

class Human2 {
	int age;
	String name;
	
	Human2(int age, String name) {
		this.age = age;
		this.name = name;
	}
	
	Human2(float birth, String name) {
		this(0, name);    // Human2(int age, String name) 생성자를 호출하는 코드
		LocalDate now = LocalDate.now();
		this.age = now.getYear() - (int) birth + 1;
		
		// 확인용
		System.out.println(now.getYear());    // 2024
		System.out.println((int) birth);      // 1989 <-- 1989.10f
	}
	
	void intro() {
		System.out.println("안녕, " + age + "살 " + name + "이야");
	}
}

class Student2 extends Human2 {
	int stNum;
	String major;
	
	Student2(int age, String name, int stNum, String major) {
		super(age, name);
		this.stNum = stNum;
		this.major = major;
	}
	
	Student2(float birth, String name, int stNum, String major) {
		super(birth, name);
		this.stNum = stNum;
		this.major = major;
	}
	
}

public class Super {
	
	public static void main(String[] args) {
		Student2 no = new Student2(39, "노정란", 9908123, "건축");
		no.intro();
		Student2 bae = new Student2(1989.10f, "백지영", 1125034, "간호");
		bae.intro();
		
		System.out.println(bae.age);
		System.out.println(bae.name);
	}

}

 

 

 

 

Overriding1.class

package chapter09.inheritance;

public class Overriding1 {

	public static void main(String[] args) {
		/*
		    메서드 오버라이딩 조건
		    1. 상속관계에서만 가능
		    2. 부모가 가지고 있는 메서드의 파라미터의 타입, 개수, 선서가 동일
		       메서드의 이름 동일, 리턴타입 동일
		*/
		
		class A {
			int num = 10;
			
			public void methodA() {
				System.out.println("A: " + num);
			}
		}
		
		class B extends A {
			int num = 100;
			
			@Override
			public void methodA() {
				System.out.println("B: " + num);
			}
		}
		
		A aa = new A();
		A ab = new B();
		B bb = new B();
		
		// 멤버 변수는 참조 타입(aa 등의 변수 앞에 정의된 타입)에 의해 결정됨
		System.out.println(aa.num);
		System.out.println(ab.num);
		System.out.println(bb.num);
		
		// 멤버 메서드는 생성타입(new 키워드 뒤에 정의된 타입)에 의해 결정됨
		aa.methodA();
		ab.methodA();
		bb.methodA();

	}

}

 

 

 

 

Overriding2.class

package chapter09.inheritance;

class Human3 {
	int age;
	String name;
	
	Human3(int age, String name) {
		this.age = age;
		this.name = name;
	}
	
	void intro() {
		System.out.println("안녕, " + age + "살 " + name + "이야");
	}
}

class Student3 extends Human3 {
	int stNum;
	String major;
	
	Student3(int age, String name, int stNum, String major) {
		super(age, name);
		this.stNum = stNum;
		this.major = major;
	}
	
	@Override
	void intro() {
		System.out.println(major + "학과 " + stNum + "학번 " + name + "입니다.");
	}
	
	void study() {
		System.out.println("스터디 스터디");
	}
}

public class Overriding2 {

	public static void main(String[] args) {
		Human3 kim = new Human3(29, "김상혁");
		kim.intro();
		
		Student3 lee = new Student3(42, "이승우", 9312345, "경영");
		lee.intro();
		lee.study();

	}

}

 

 

 

 

Final.class

package chapter09.inheritance;

// final class는 상속 불가함
class AA {
	final static double PI = 3.14;
	
	void method() {
		System.out.println("method 실행");
	}
	
	final void finalMethod() {
		System.out.println("final method 실행");
	}
}

class BB extends AA {
	@Override
	void method() {
		super.method();
		System.out.println("method BB 실행");
	}
}

public class Final {

	public static void main(String[] args) {
		/*
		    final
		    - final 변수 : 상수, 값 변경 불가함
		    - final 클래스 : 상속 불가함
		    - final 메서드 : override 불가함
		*/
		
		AA aa = new AA();
		AA ab = new BB();
		BB bb = new BB();
		
		System.out.println(aa.PI);
		System.out.println(ab.PI);
		System.out.println(bb.PI);
		// aa.PI = 3123.432525;     // final 변수는 재할당 불가함
		
		aa.method();
		aa.finalMethod();
		ab.method();
		ab.finalMethod();
		bb.method();
		bb.finalMethod();

	}

}

 

 

 

 

Is_a.class

package chapter09.inheritance;

class Animal {
	String name;
	
	void move() {
		System.out.println("움직이다");
	}
}

class Human4 extends Animal {
	@Override
	void move() {
		System.out.println("걷다");
	}
}

public class Is_a {

	public static void main(String[] args) {
		/*
		    is a relation
		    상속 관계, 다중 상속X
		*/
		
		Animal a = new Human4();    // 사람은 동물이다 O
		Human4 b = new Human4();    // 사람은 사람이다 O
		// Human4 c = new Animal();    // 동물은 사람이다 X
		
		a.move();
		b.move();

	}

}

 

 

 

 

Has_a.class

package chapter09.inheritance;

class Tool {
	String name;   // 멤버 변수
	
	Tool(String name) {    // 생성자
		this.name = name;
	}
}

class Human5 {
	Tool tool;     // 멤버 변수
	
	Human5(String toolName) {     // 생성자
		this.tool = new Tool(toolName);   // "Tool tool = new Tool(toolName);"과 동일한 코드이다!!
	}
	
	void use() {    // 멤버 메서드
		System.out.println(tool.name + "을/를 사용하다");
	}
}

public class Has_a {

	public static void main(String[] args) {
		/*
		    has a relation
		    포함, 구성 단계
		*/
		
		Human5 h = new Human5("파이어스틸");
		System.out.println(h.tool.name);
		h.use();

	}

}