# [Java #10 / 250317] 상속

temi·2025년 3월 18일

Java

목록 보기
10/15

학원에서 학습한 내용을 개인정리한 글입니다.


수업

상속

  • 다른 클래스가 가지고 있는 멤버(필드, 메소드)를 받아 새로 작성할 클래스에서 직접 만들지 않고 상속을 받음으로써 자신의 멤버처럼 사용할 수 있는 기능

목적

  • 클래스의 재사용
  • 클래스에 대한 공통적인 규약 정의

장점

  • 적은 양의 코드로 새로운 클래스 작성 가능
  • 코드를 공통적으로 관리하기 때문에 코드 추가 및 변경 용이
  • 중복을 제거해서 생산성/유지보수에 크게 기여

특징

  • 모든 클래스는 Object 클래스의 후손
    • Object 클래스가 제공하는 메소드를 오버라이딩하여 메소드 재구현
  • 부모클래스의 생성자, 초기화 블록은 상속 안됨
    • 자식 클래스 생성보다 부모 클래스가 생성자가 먼저 실행
    • 자식 생성자 안에 부모 클래스 생성자를 호출하고 싶으면 super() 활용
  • 부모의 Private 멤버는 상속이 되지만 직접 접근 불가
    • 자식 객체 생성 시에 부모 필드 값도 전달 받은 경우 자식 생성자 안에서 부모 private 필드에 접근 대입 불가.
    • super()이용하거나 setter, getter 메소드 이용하여 접근

방법, 표현식

  • 클래스 간의 상속 시에는 Extends 키워드 사용
[접근제한자] class 클래스명 extends 클래스명 {}
public class Academy extends Company {}
💡

QNA

?: 부모자식간의 관계에서 자식이 몇대까지 내려올수있는지..? e.g. 부모의 자식, 자식의 자식, 그. 자식의 자식의 자식?

Teacher: 계층구조로 나눠서 하는 건 가능! 근데 위에서부터 아래까지 쭉 내려올거라면 잘 생각해서 설계해야할 것..

단일 상속

  • 자바는 단일 상속만 지원
  • 다중 상속보다 명확하고 신뢰성 있는 코드 작성

다중 상속

  • C++에서 가능한 기능으로, 여러 클래스로부터 상속을 받음
  • 복합적인 기능을 가진 클래스를 쉽게 작성 가능
  • 서로 다른 클래스로부터 상속 받은 멤버 간의 이름이 같은 경우 문제 발생

super()

  • 부모 생성자를 호출하는 메소드채

super.

  • 상속을 통한 자식 클래스 정의 시 해당 자식 클래스의 부모 객체를 가리키는 참조변수
  • 자식 클래스 내에서 부모 클래스 객체에 접근하여 필드, 메소드 호출 사용
💡

QNA

Temi: parent를 상속받은 child가 child 안에서 상속받은 필드 변수를 수정하면 부모의 값이 바뀌는건지?

Teacher : 안바뀐다. child new 로 생길때마다 새로운 인스턴스가 생기는거다. 다른 child가 생기더라도 각자의 값을 가질 수 있다

public void basicInherit() {
		//기본 상속에 대해 알아보자
		//선언 되어 있는 클래스의 내용을 가져와 사용
		//클래스간의 관계를 설정
		//클래스 선언부에 extend 예약어를 사용해서 설정
		//e.g. public class Child(sub) extends Parent(super){}
		A_Child child = new A_Child();
		child.gender = '남';
		child.test();
		System.out.println(child.gender);
		child.setData("오");
		System.out.println(child.getData());
		
		A_Child child2= new A_Child();
		System.out.println(child2.gender);
		
		//부모 클래스의 필드, 메소드에 접근할 때 부모 클래스에 선언된 접근제한자 우선처리
//		child2.weight = 66.4;
	}
	public A_Parent(String data) {
		this.data = data;
	}
public class A_Child extends A_Parent{
	private String[] names;
	
	public A_Child() {
		super("우와 ");
	}
	
	public void childTest() {
		//data = "hi"; // private 라 접근 X
		//getter. setter 를 이용하여 접근
		
		setData("안녕");
		//protected 접근 제한자는 자식 클래스에서 직접접근이 가능
		weight = 65.5;
	}
}
public class A_Child2 extends A_Parent{
	//부모는 여러명의 자식을 가질 수 있다
	private int[] numbers;
	public void setNumbers(int[] numbers) {
		this.numbers = numbers;
	}
	public int[] getNumbers() {
		return numbers;
	}
}

실습

부모, 부모를 상속받는 여러 자식

  • 사람이라는 객체를 만들고 강사, 회사원, 개발자, 학생 등 이어받는 자식을 만들고 적용해볼 것
  • 이렇게 한다면 나중에 서로 공유하고 있는 필드 멤버의 타입을 바꿔야 할 일이 있을 때도 쉽게 수정할 수 있다(e.g. gender를 스트링으로 바꿔야할때)
package com.inherit.model.vo;

public class Person {
	protected  String name;
	protected int age;
	protected char gender;
	
	public Person() {
		
	}
	public Person(String name, int age, char gender) {
		this.name = name;
		this.age = age;
		this.gender = gender;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public char getGender() {
		return gender;
	}

	public void setGender(char gender) {
		this.gender = gender;
	}
}
package com.inherit.model.vo;

public class Developer extends Person {
	private int experience;
	private String majorLanguage;
	
	public Developer() {
		
	}
	
	public Developer(String name, int age, char gender, int experience, String majorLanguage) {
		super.setName(name);
		super.setAge(age);
		super.setGender(gender);
		this.experience = experience;
		this.majorLanguage = majorLanguage;
	}
	public int getExperience() {
		return experience;
	}
	public void setExperience(int experience) {
		this.experience = experience;
	}
	public String getMajorLanguage() {
		return majorLanguage;
	}
	public void setMajorLanguage(String majorLanguage) {
		this.majorLanguage = majorLanguage;
	}
	public void inform() {
		System.out.println(super.name + " " + super.age + " " + super.gender + " " + this.experience + " " + this.majorLanguage);
	}
}

Developer dp = new Developer("aaa", 15, 'f', 5, "java");
dp.inform();
Instructor i = new Instructor("ㅇㅇㅇ", 20, 'm',  5, "국어", 5000);
i.inform();
OfficeWorker o = new OfficeWorker("OOO", 15, 'f', 12, "daasd", "dsad");
o.inform();
Student s = new Student("AAA", 24, 'f', 3, "컴공","한국대학교");
s.inform();

오버라이딩 Overriding

  • 자식 클래스가 상속 받은 부모 메소드를 재작성 하는 것
  • 부모가 제공하는 기능을 일부 고쳐 사용
  • 자식 객체를 통한 실행시 후손이 우선권을 가짐

특징

  • 메소드 헤드라인 위에 반드시 Annotation, @Override 표시
  • 접근 제어자를 부모 것보다 같거나 넓은 범위로 변경 가능
  • 부모 메소드의 예외처리 클래스 처리범위보다 좁은 범위로 예외처리 클래스 수정 가능

성립 조건

  • 메소드 이름 동일
  • 매개변수 개수, 타입. 동일
  • 리턴 타입 동일
  • private, final 메소드 오버라이딩 불가

오버로딩 overloading

  • 한 클래스 내에서 같은 이름의 메소드를 여러 개 정의하는 것

성립 조건

  • 같은 메소드 이름
  • 다른 매개변수 선언부

주의 사항

  • 리턴 타입은 오버로딩 조건과 관계 없음
오버라이딩오버로딩
하위 클래스에서 메소드 정의같은 클래스에서 메소드 정의

| 메소드 이름 동일
매개변수 동일
리턴타입 동일 | 메소드 이름 동일
매개변수 다름(개수, 타입)
리턴 타입 상관 없음 |
| 자식 메소드의 접근 범위가 부모 메소드의 접근 범위보다 넓거나 같아야함 | 접근 제어자와 상관 없음 |
| 자식 메소드의 예외 수가 부모 메소드의 예외 수보다 적거나 범위가 좁아야 함 | 예외처리와 상관 없음 |

오버라이딩 예시

  • 동물 부모를 받은 강아지, 고양이
  • 각자 울음소리와 움직임이 다르기때문에 오버라이딩함
  • 오버라이딩한 메소드 위에는 @Override를 꼭 써서 확인하자!!!
package com.inherit.model.vo;

public class C_Animal {
	private String name;
	private int age;
	private double weight;
	
	public C_Animal() {
		
	}
	
	public C_Animal(String name, int age, double weight) {
		super();
		this.name = name;
		this.age = age;
		this.weight = weight;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public double getWeight() {
		return weight;
	}
	public void setWeight(double weight) {
		this.weight = weight;
	}
	
	public void move() {
		System.out.println(name + " 앞으로 움직임");
	}
	
	public void bark() {
		System.out.println(name + " 울어요");
	}
}
package com.inherit.model.vo;

public class C_Dog extends C_Animal{
	public C_Dog() {
		
	}
	public void move() {
		System.out.println(getName() + "이 우당탕탕 움직임");
	}
	@Override
	public void bark() {
		System.out.println(getName() + "이 멍멍멍 짖음");
	}
}
package com.inherit.model.vo;

public class C_Cat extends C_Animal{
	public C_Cat() {
		
	}
	public void move() {
		System.out.println(getName() + "이 사뿐사뿐 움직임");
	}
	@Override
	public void bark() {
		System.out.println(getName() + "이 야오옹 울음");
	}
}
public class C_OverrideController {
	public void overrideTest() {
		C_Dog dog = new C_Dog();
		dog.setName("덕만");
		dog.setAge(5);
		dog.setWeight(5.5);
		dog.move();
		dog.bark();
		
		C_Cat cat = new C_Cat();
		cat.setAge(4);
		cat.setName("김춘식");
		cat.setWeight(6.1);
		cat.move();
		cat.bark();
	}
	
}
💡

QNA

Temi: 한정적으로 상속을 받을 수도 있는건지? 필요없는게 있을 수 있다.

Teacher : 가능하다. Interface라는 것이 있는데 추후에 배울 것. 지금은 디폴트 값을 다르게 하고 서로 약속을 해두면 된다.

Object 클래스

  • 자바에서 기본적으로 제공하는 클래스
  • 최상위 클래스 → 자바에서 사용하는 모든 클래스의 부모
  • root 클래스
  • extends 예약어로 상속관계를 설정하지 않아도 자동으로 설정

equals()

  • 객체의 동등성 비교를 하기 위한 메소드

hashCode()

  • 객체에 부여된 숫자 Id값을 반환하는 메소드

clone()

  • 객체의 사본을 생성하는 메소드 -> 깊은 복사

toString()

  • 객체를 대표하는 문자열을 반환하는 메소드

자바 Object 메소드 오버라이딩

	@Override
	public String toString() {
		return no +" "+ name;
	}

	@Override
	public boolean equals(Object obj) {
		//this값, 매개변수 객체와 비교
		//동등한 값에 대한 기준을 설정
		D_ObjectTest param = (D_ObjectTest)obj;
		
		if(this.no == param.no && this.name.equals(param.name)) {
			return true;
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		return Objects.hash(no, name);
	}
	
	@Override
	public D_ObjectTest clone() {
		return new D_ObjectTest(no, name);
	}

java doc

final 예약어

  • 상속을 주면서 바꾸고 싶지 않은 값이 있을 때 final을 쓸 수 있다.
  • 상속받은 메소드를 재선언해서 사용하고 있는 메소드를 final로 수정하자마자 오류가 난다.


미리 준비

  • 실습과제 2개, 기존 과제 정리 필요
  • 학생관리 시스템 버전 나누기(이슈 못고친버전이랑 기존버전)

느낀점

  • 이론 수업이 이어질때 좀 이해안가는 부분들이 있는데 이건 시간이 필요한 것 같다.. 학원에서 좀 더 이해할 수 있는 시간을 주면 좋겠는데 6개월 간에 마무리를 해야하는거니까 어쩔순없지만 ㅠㅠ

profile
250304~

0개의 댓글