230721

객체지향 프로그래밍 (3) - 상속

  • 상속
  • Object 클래스
  • final 키워드

상속 (Inheritance)


어떤 클래스의 특성을 그대로 갖는 새로운 클래스를 정의한 것

상속

조상클래스의 상속을 받아 만든 하위, 자식 클래스

상속1

public class Person {
	String name;
	int age;
	public void eat() {
		System.out.println("음식을 먹는다.);
	}
]

상속2

public class Student {
	String name;
	int age;
	String major;
	public void eat() {
		System.out.println("음식을 먹는다.");
	}
	public void study() {
		System.out.println("공부를 한다.");
	}
}
public class Person {
	String name;
	int age;
	public void eat() {
		System.out.println("음식을 먹는다.");
	}
}
public class Student extends Person {
	String major;
	public void study() {
		System.out.println("공부를 한다.");
	}
}

extends 라는 키워드를 이용해서 Person을 적어 주기만 하면 Student에서 Person에 있는 속성들을 사용할 수 있다

상속3

여기서도: 오른쪽에서 Student를 선언했는데, Person이 나옴… Person의 속성을 상속받았다는 뜻

다형성

→ 다양한 이름으로 불릴 수 있음!

Person p = new Person();
Student st = new Student();
Person p1 = new Student();

Object?

모든 클래스의 조상 클래스

상속4

상속

1. 확장성, 재사용성

→ 부모의 생성자와 초기화 블록은 상속 X

2. 클래스 선언 시 extends 키워드를 명시

→ 자바는 다중 상속 허용 X, 단일 상속 지원?

extends A, B 안 됨 extends A

헷갈려!~

하지만 비슷한 효과를 낼 수는 있음 (다음 주에…)

3. 관계

→ 부모 (상위, Super) 클래스: Person

→ 자식 (하위, Sub) 클래스: Student

4. 자식 클래스는 부모 클래스의 멤버 변수, 메소드를 자신의 것처럼 사용할 수 있다

(단, 접근 제한자에 따라 사용 여부가 달라진다.)

5. Object 클래스는 모든 클래스의 조상 클래스

→ 별도의 extends 선언이 없는 클래스는 extends Object가 생략되어 있다는 뜻

6. super 키워드

→ super를 통해 조상 클래스의 생성자 호출

public class Person {
	String name;
	int age;
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public void eat() {
		System.out.println("음식을 먹는다");
	}
}
public class Student extends Person {
	String major;
	public Student(String name, int age, String major) {
		super(name, age);
		this.major = major;
	}
	public void study() {
		System.out.println("공부를 한다.");
	}
}

7. 오버라이딩 (재정의, overriding)

  • 상위 클래스에 선언된 메서드를 자식 클래스에서 재정의하는 것
  • 메서드의 이름, 반환형, 매개변수 (타입, 개수, 순서) 동일해야 한다
  • 하위 클래스의 접근제어자 범위가 상위 클래스보다 크거나 같아야 한다
  • 조상보다 더 큰 예외를 던질 수 없다
  • 메서드 오버로딩(overloading)과 혼동하지 말 것!

Object


Object 클래스

  • 가장 최상위 클래스로 모든 클래스의 조상
  • Object의 멤버는 모든 클래스의 멤버

상속5

System.out.println(person.toString()); // Object의 toString 사용
System.out.println(student.toString()); // Student의 toString 사용

toString 메서드

  • 객체를 문자열로 변경하는 메서드
    public String toString() {
    	return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
    
  • 정작 궁금한 내용은 주소 값이 아닌 내용임!!
    public String toString() {
    	return "Student [name=" + name + ", age=" + age + ", major=" + major + "]";
    }
    

equals 메서드

  • 두 객체가 같은지 비교하는 메서드
    public boolean equals(Object obj) {
    	return (this == obj);
    }
    

    비교연산자 == 로 두 객체의 주소 값 비교

  • 두 개의 레퍼런스 변수가 같은 객체를 가리키고 있는가?
    Object obj1 = new Object();
    Object obj2 = new Object();
    Object obj3 = obj2;
    System.out.printf("obj1 == obj2: %b\n", obj1==obj2);
    System.out.printf("obj1 equals obj2: %b\n", obj1.equals(obj2));
    System.out.printf("obj2 == obj3: %b\n", obj2==obj3);
    System.out.printf("obj2 equals obj3: %b\n", obj2.equals(obj3));
    
  • 우리가 비교할 것은 정말 객체의 주소 값인가?

    • 두 객체의 내용을 비교할 수 있도록 equals 메서드 재정의!

      private static void testString() {
      	String s1 = new String("Hello");
      	String s2 = new String("Hello");
      	System.out.println((s1 == s2) + " : " + s1.equals(s2));
      }
      
      private static void testPhone() {
      	Phone p1 = new Phone("0100000000");
      	Phone p2 = new Phone("0100000000");
      	System.out.println((p1 == p2) + " : " + p1.equals(p2));
      }
      

      객체의 주소 비교: == 활용 객체의 내용 비교: .equals 재정의 String 클래스에는 equals가 내용을 비교하는 것으로 재정의되어 있음! 객체의 경우에도 똑같이 해 줘야 한다 → equals (instanceof String)

      class Phone {
      String number = "전화번호";
      public Phone(String number) {
      	this.number = number;
      	}
      	/*
      	@Override
      	public boolean equals(Object obj) {
      	if (obj != null && obj instanceof Phone) {
      	Phone casted = (Phone) obj;
      	return number.equals(casted.number);
      	}
      	return false;
      	}
      	*/
      }
      

hashCode

  • 객체의 해시 코드: 시스템에서 객체를 구별하기 위해
  • HashSet, HashMap 등에서 객체의 동일성을 확인하기 위해 사용 상속7
  • equals 메서드를 재정의할 때는 반드시 hashCode도 재정의할 것
  • 미리 작성된 Strinng이나 Number 등에서 재정의된 hashCode 활용 권장

final


final이란?

  • 해당 선언이 최종 상태, 절대 수정될 수 없음
  • final 클래스: 상속 금지
  • final 메소드: overriding 금지
  • final 변수: 더 이상 값을 바꿀 수 없음. 상수화