[JAVA]_7일차

전희주·2023년 4월 13일
0

JAVA

목록 보기
7/24
post-thumbnail

상속

클래스들 간의 관계

  • 1) 종류

    • 분석 단계

      • has a (use a) : 학생 has a(use a) 컴퓨터
      • is a : 대학생 is a 학생
      • x : cat is a pet
    • 설계 단계

      • 분석 단계의 내용을 코딩(oop 사용)으로 표현
  • 2) 종류

has a 표현

public class 학생 { 
 string name; 
 컴퓨터 p; // 학생 has 컴퓨터를 은연 중 표현~ 
}

is a 표현

- 1) is a 관계: 
대학생 is a 학생
고양이 is a 애완동물
개발자 is a 사원

- 2) 애완동물 관리 프로그램 

 ![](https://velog.velcdn.com/images/heejoojeon/post/2fce08ab-927e-4448-9588-90816d2911dd/image.png)
 - Cat, Dog, Bird 간에는 관계 없음 
 - 상속 관계(is-a) 로 선언되면, 부모의 변수, 메서드를 자식이 선언 없이 사용 가능 (생성자, private은 상속 불가) 

상속 특징

  • 상속의 특징
    • 부모 클래스 → Super class
    • 자식 클래스 → Sub class
    • 자바는 다중 상속을 지원 하지 X → extends 뒤에는 하나의 부모 클래스만 올수 있다.
    • 상속 횟수에 제한 X
    • 자바의 최상위 클래스는 Object 이다.
      • Object는 java.lang package 내 존재
      • extends Object (자동 지정)
    • 즉 자바의 모든 클래스는 Object 의 자손 (명시적으로 나타나진않음)
    • Object의 메서드를 그냥 사용이 가능하다.
    • 객체 생성 시 항상 부모를 먼저 생성한다.
      • 자식 객체 생성시 부모 객체가 먼저 생성되고 이후에 자식 객체가 생성된다
      • 부모가 먼저 생성되어야 자식이 부모의 멤버(변수.메서드)를 그냥 사용할 수 있다.

+) 생성자 호출 및 정의 리뷰

super 키워드

  • 1) heap 메모리에 생성된 부모의 instance 참조
  • 2) 용도: 부모의 인스턴스 변수와 자식의 변수명이 동일한 경우
    • class Pet { int n; }
    • class Cat extends Pet { int n; }
    • 부모 생성자 호출
      예)
      • super ( );
      • super (값, 값2);
  • 반드시 첫 줄에 기재
    cf. this 키워드
public class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
        System.out.println("Animal 생성자 호출");
    }
}
public class Cat extends Animal {
    public Cat(String name) {
        super(name); // 부모 클래스의 생성자 호출
        System.out.println("Cat 생성자 호출");
    }
}

명시적으로 Super(값, 값2...) 요청하는 경우

  • 자식클래스에서 super( )키워드 사용하여 부모 클래스의 생성자 호출 가능
  • 부모의 인스턴스 변수를 자식이 아닌 부모에서 초기화하기 위함

오버라이딩(overriding) 메서드

  • 1) 상속 전제
  • 2) 개념:자바에서는 메소드 오버라이딩을 통해 상속받은 부모 클래스의 메소드를 자식 클래스에서 직접 재정의할 수 있음.
  • 3) 문법: 메서드 이름, 매개변수 타입, 개수, 반환 타입이 동일해야 함 (접근 지정자는 달라도 됨)
    • 메서드 이름은 부모 클래스와 동일다.
    • 매개변수의 타입과 개수는 부모 클래스와 동일
    • 반환 타입은 부모 클래스와 동일하거나 부모 클래스의 반환 타입을 하위 타입으로 가지는 타입이어야 함
    • 접근 지정자는 부모 클래스의 메서드보다 더 넓은 범위의 접근 지정자를 사용할 수 있음.
      • 예를 들어, 부모 클래스의 메서드가 protected로 선언되어 있다면, 오버라이딩하는 자식 클래스의 메서드는 protected 또는 public으로 선언할 수 있음
        => ✨ private 불가
  • ✨ static, final, 접근지정자 private 부모 메서드 재정의 불가

+) 오버라이딩을 사용하는 이유
: 상속 관계에서 부모 클래스의 메서드를 자식 클래스에서 필요에 따라 수정하거나 보완하기 위해서임
이를 통해 코드의 재사용성을 높이고, 유지보수를 용이하게 할 수 있음

class Animal {
   public void makeSound() {
      System.out.println("The animal makes a sound");
   }
}

class Dog extends Animal {
   @Override
   public void makeSound() {
      System.out.println("Woof");
   }
}

class Cat extends Animal {
   @Override
   public void makeSound() {
      System.out.println("Meow");
   }
}

public class Main {
   public static void main(String[] args) {
      Animal myAnimal = new Animal();
      Animal myDog = new Dog();
      Animal myCat = new Cat();

      myAnimal.makeSound(); // 출력: The animal makes a sound
      myDog.makeSound(); // 출력: Woof
      myCat.makeSound(); // 출력: Meow
   }
}
  • "@Override" 어노테이션
    • 자바에서는 "@Override" 라는 어노테이션(annotation)을 제공하여 오버라이딩이 제대로 이루어졌는지를 확인
class Animal {
   public void makeSound() {
      System.out.println("The animal makes a sound");
   }
}

class Dog extends Animal {
   @Override
   public void makeSound() {
      System.out.println("Woof");
   }
}
  • 자동 오버라이딩 지정

오버라이딩과 다형성

다형성

  • 1) 상속전제
  • 2) 개념: 하나의 참조변수가 서로 다른 타입을 참조할 수 있는 능력(성질) 의미
  • 3) 기본 문법:
    Pet p = new Cat ();
    p = new Dog();
  • 4) 특징
    • 동적 바인딩 적용 : ✨ 메서드만 적용, 변수에는 적용x
    • p가 컴파일 시 Pet인식하고, 실행시 new한, 실제 생성된 객체로 인식
  • 5) 활용
    • 가) 배열
      • 다형성을 이용하여 배열에 여러 종류의 객체를 저장할 수 있음.
Pet[] pets = { new Cat("야옹이", "암컷", 2), new Dog("멍멍이", "수컷", 3, "진돗개"), new Bird("짹짹이", "암컷", "노랑") };
for (Pet p : pets) {
    System.out.println(p.getName());
}
  • Java에서 Object 클래스는 모든 클래스의 부모 클래스이므로, 모든 매개변수에 대해 다형성을 제공.
  • 즉, Object 타입의 매개변수를 사용하여 모든 자식 클래스의 객체를 전달할 수 있음.
public void myMethod(Object obj) {
    // 메서드 내용
}
Animal myAnimal = new Animal();
Cat myCat = new Cat();
Dog myDog = new Dog();

myMethod(myAnimal); // Object 타입으로 형변환되어 전달됨
myMethod(myCat); // Object 타입으로 형변환되어 전달됨
myMethod(myDog); // Object 타입으로 형변환되어 전달됨

  • 예)
  • Animal, Dog, Cat 클래스가 모두 Animal 클래스를 상속
class Animal {
   public void makeSound() {
      System.out.println("The animal makes a sound");
   }
}

class Dog extends Animal {
   @Override
   public void makeSound() {
      System.out.println("Woof");
   }
}

class Cat extends Animal {
   @Override
   public void makeSound() {
      System.out.println("Meow");
   }
}

public class Main {
   public static void main(String[] args) {
      Animal myAnimal = new Animal();
      Animal myDog = new Dog();
      Animal myCat = new Cat();

      myAnimal.makeSound(); // 출력: The animal makes a sound
      myDog.makeSound(); // 출력: Woof
      myCat.makeSound(); // 출력: Meow
   }
}
  • Animal myAnimal = new Animal()은 Animal 클래스의 객체를 생성하는 것

  • Animal myDog = new Dog()와 Animal myCat = new Cat()는 각각 Dog 클래스와 Cat 클래스의 객체를 생성하면서 Animal 클래스로 형변환하여 참조하고 있는 것입니다.

  • 이러한 성질을 "다형성(Polymorphism)"이라고 부르며, 자바에서는 상속과 오버라이딩을 통해 이러한 다형성을 구현할 수 있습니다.

동적 바인딩

class Animal {
    public void makeSound() {
        System.out.println("Animal is making a sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog is barking");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Dog dog = new Dog();

        Animal a = new Dog(); // 다형성을 이용한 상위 클래스 타입의 변수에 하위 클래스 객체 할당
        animal.makeSound(); // Animal is making a sound
        dog.makeSound(); // Dog is barking
        a.makeSound(); // Dog is barking (동적 바인딩 적용)
    }
}
  • Dog 클래스가 Animal 클래스를 상속받고 있습니다. Animal 클래스에는 makeSound() 메서드가 정의되어 있고 Dog 클래스에서는 이 메서드를 오버라이딩하여 재정의했습니다.

  • main() 메서드에서 Animal 클래스와 Dog 클래스로 객체를 생성하고, Animal 클래스 타입의 a 변수에 Dog 클래스 객체를 할당합니다. 이렇게 하면 a 변수는 Animal 클래스 타입으로 선언되어 있지만, 런타임 시 Dog 클래스의 객체를 참조하게 됩니다.

  • m a.makeSound()에서는 a 변수가 참조하는 객체가 Dog 클래스이므로, Dog 클래스에서 오버라이딩한 makeSound() 메서드가 호출되어 "Dog is barking"이 출력됩니다.

  • 실행 시점에서 객체의 실제 타입을 확인하여 적절한 메서드를 호출하는 것이 바로 동적 바인딩입니다.

Object 클래스

  • java.lang.Object

  • 모든 클래스의 최상위 클래스

  • clone(), equals(), hashCode(), toString()을 흔히 override해서 사용

  • object의 toString()

    • extends Object 자동 삽입
    • 자동으로 호출됨
    • 호출 시점: 참조 변수를 print할 때
    • 예)
      • String s = "hello";
      • 침조 변수는 주소값인데 문자열로 출력하기 위해 자동으로 object의 toString() 실행
      • String 클래스의 인스턴스를 생성하고, 이를 참조하는 변수 s에 할당합니다. 이때, s 변수는 문자열 "hello"를 가리키는 참조 변수가 됩니다.
      • 문자열 변수 s를 출력하면, s 변수가 가리키는 객체의 문자열 표현이 출력됩니다.

Object 클래스의 재정의

  • Object 클래스에서 상속받은 toString() 메서드는 객체의 해시 코드와 클래스 이름을 문자열로 반환하도록 구현되어 있습니다.
  • 하지만 각 클래스는 필요에 따라 toString() 메서드를 재정의하여 자신만의 문자열 표현 방법을 제공할 수 있습니다.
  • 예를 들어, String 클래스에서는 문자열 값을 그대로 반환하는 toString() 메서드를 구현하여, String 객체의 문자열 값이 출력됩니다.
  • 또한, Date 클래스에서는 현재 날짜와 시간을 문자열로 반환하는 toString() 메서드를 구현하여, Date 객체의 날짜와 시간 정보가 출력됩니다.
  • 이러한 방식으로 각 클래스는 자신만의 문자열 표현 방법을 제공할 수 있습니다.
package p05;
import java.util.Date;
public class TestPet3 {

	public static void main(String[] args) {

		Cat c = new Cat("야옹", "암컷", 2); 
		
		// Cat 클래스에서 toString() 메서드를 재정의하지 않음
		// Object 클래스에서 상속받은 기본 toString() 메서드가 호출
		System.out.println(c);
		System.out.println(c.toString()); // Cat@16진수
		
		////////////////////////////////////API (우리가 만든 클래스가 아니라 내장된 것)
		// String 클래스와 Date 클래스는 Java API (Application Programming Interface)에 포함된 클래스
		// s는 String 클래스의 인스턴스
		// String 클래스에서 toString() 메서드는 인스턴스 자신을 반환
		String s = "hello"; 
		System.out.println(s); // 참조변수, 자동으로 toString() 호출됨 
		System.out.println(s.toString()); //hello 
		
		//  d는 Date 클래스의 인스턴스
		Date d = new Date(); 
		System.out.println(d);// d.toString()과 동일한 결과를 출력 
		System.out.println(d.toString()); // 2023~
		
	}
}
  • 자동 재정의

0개의 댓글