[Java 초급] 3. 패키지와 클래스 활용법: 생성자와 상속

Kyung Jae, Cheong·2024년 8월 22일
0
post-thumbnail

3. 패키지와 클래스 활용법: 생성자와 상속

  • Java에서 패키지는 클래스와 인터페이스를 묶는 컨테이너 역할을 하며, 클래스는 객체를 생성하고 행동을 정의하는 설계도입니다.
  • 이 섹션에서는 패키지와 클래스의 활용법(특히 생성자와 상속)에 대해 설명하겠습니다.

3-1. 패키지 (Package)

  • 패키지는 관련된 클래스와 인터페이스를 그룹화하여 구조적으로 관리하는 데 사용됩니다.
  • 패키지를 사용하면 네임스페이스 충돌을 방지하고, 코드의 재사용성과 유지보수성을 높일 수 있습니다.

패키지 선언

  • 패키지는 소스 파일의 맨 위에서 선언하며, 패키지 이름은 일반적으로 회사 도메인 이름을 역순으로 하여 고유성을 확보합니다.
    • 관례이긴하지만, 공개적으로 코드를 배포할때는 꼭 숙지해 두시는것이 좋습니다.
package com.example.myapp;
  • 위의 예제에서 com.example.myapp은 패키지 이름입니다. 해당 패키지에 포함된 모든 클래스는 이 패키지 내에서 관리됩니다.
    • 패키지명은 모두 소문자로 나타내야합니다. (관례)
    • a.b.c 라는 패키지와 a.b라는 패키지가 있을때 a.ba.b.c는 관계가 있어보이지만, 전혀 다른 패키지로 인식되어 동작한다는 점도 알아주시는게 좋습니다.

패키지 사용

  • 다른 패키지에 있는 클래스를 사용하려면 import 문을 사용하여 해당 클래스를 가져와야 합니다.
import java.util.Scanner;  // java.util 패키지의 Scanner 클래스 임포트

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // ...
    }
}
  • java.util.Scanner는 Java의 표준 라이브러리 패키지 중 하나입니다. import를 사용하면 클래스 이름을 직접 사용할 수 있습니다.
    • 참고로 불러온 패키지들의 이름이 겹치는 경우, 하나만 선택하여 import하고 다른 패키지는 경로를 모두 입력해주셔야합니다.

3-2. 클래스 활용: 생성자(Constructor)

  • 생성자는 객체가 생성될 때 호출되는 특수한 메서드로, 객체의 초기화에 사용됩니다.
    • 생성자는 클래스 이름과 동일하며, 반환 타입이 없습니다.

기본 생성자

  • 기본 생성자는 매개변수가 없는 생성자입니다. 클래스에 생성자가 정의되지 않으면, Java 컴파일러가 자동으로 기본 생성자를 생성합니다.
public class Person {
    String name;
    int age;

    // 기본 생성자
    public Person() {
        name = "Unknown";
        age = 0;
    }

    public void introduce() {
        System.out.println("My name is " + name + " and I am " + age + " years old.");
    }
}

매개변수가 있는 생성자

  • 매개변수가 있는 생성자는 객체 생성 시 초기 값을 설정할 수 있도록 합니다.
public class Person {
    String name;
    int age;

    // 매개변수가 있는 생성자
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce() {
        System.out.println("My name is " + name + " and I am " + age + " years old.");
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30);
        person.introduce();  // 출력: My name is Alice and I am 30 years old.
    }
}

생성자 오버로딩

  • 생성자 오버로딩은 클래스 내에서 여러 개의 생성자를 정의하는 것을 말합니다.
    • 생성자마다 다른 매개변수를 가질 수 있습니다.
public class Person {
    String name;
    int age;

    // 기본 생성자
    public Person() {
        this.name = "Unknown";
        this.age = 0;
    }

    // 매개변수가 있는 생성자
    public Person(String name) {
        this.name = name;
        this.age = 0;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce() {
        System.out.println("My name is " + name + " and I am " + age + " years old.");
    }
}

3-3. 클래스 활용: 상속

  • 상속은 객체지향 프로그래밍의 핵심 개념으로, 기존 클래스(부모 클래스)의 속성과 메서드를 새로운 클래스(자식 클래스)가 물려받아 사용하는 기능입니다.
    • 이를 통해 코드의 재사용성과 확장성을 높일 수 있습니다.
  • 다형성에 대해 다룰 때 다시 상세히 다룰 예정입니다.

3-3-1.기본적인 상속

  • 상속은 extends 키워드를 사용하여 구현됩니다.
// 부모 클래스
public class Animal {
    String name;

    public void eat() {
        System.out.println(name + " is eating.");
    }
}

// 자식 클래스
public class Dog extends Animal {

    public void bark() {
        System.out.println(name + " is barking.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "Buddy";
        dog.eat();   // 부모 클래스에서 상속받은 메서드 호출
        dog.bark();  // 자식 클래스에서 정의한 메서드 호출
    }
}
  • 위의 예시에서 Dog 클래스는 Animal 클래스를 상속받아 eat() 메서드를 사용할 수 있습니다. 또한 Dog 클래스는 자신만의 메서드 bark()를 추가로 정의할 수 있습니다.

3-3-2. 메서드 오버라이딩

  • 메서드 오버라이딩은 부모 클래스에서 상속받은 메서드를 자식 클래스에서 재정의하는 것입니다.
    • 오버라이딩을 통해 자식 클래스는 부모 클래스의 메서드를 자신의 방식으로 구현할 수 있습니다.
    • 다형성에 대해서 다룰때 다시 자세히 다룰 예정입니다.
public class Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

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

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

        myAnimal.sound();  // 출력: Animal makes a sound
        myDog.sound();     // 출력: Dog barks (오버라이딩된 메서드 호출)
    }
}
  • 참고로 메서드 위에 @Override를 안 붙여도 동작은 하는데 가능한 붙여주시는 것이 좋습니다. 오버라이딩시 실수에 의한 에러를 방지할 수 있고 가독성도 높일 수 있기 때문입니다.

3-3-3. super 키워드

  • super 키워드는 자식 클래스에서 부모 클래스의 메서드나 생성자를 호출할 때 사용됩니다. (물론 변수를 불러오는데에도 쓰입니다.)
public class Animal {
    String name;

    public Animal(String name) {
        this.name = name;
    }

    public void sound() {
        System.out.println(name + " makes a sound");
    }
}

public class Dog extends Animal {

    public Dog(String name) {
        super(name);  // 부모 클래스의 생성자 호출
    }

    @Override
    public void sound() {
        super.sound();  // 부모 클래스의 메서드 호출
        System.out.println(name + " barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy");
        dog.sound();  // 출력: Buddy makes a sound
                      //       Buddy barks
    }
}
  • 위 예시에서 Dog 클래스는 부모 클래스의 생성자와 메서드를 super 키워드를 사용하여 호출합니다.

마무리

  • 패키지와 클래스를 잘 활용하면 Java 프로그램의 구조를 더 잘 조직화하고, 유지보수성을 높일 수 있습니다.
  • 생성자는 객체 초기화 시 필수적인 역할을 하며, 상속은 코드 재사용성을 높이고 객체지향의 중요한 원칙을 구현하는 데 중요한 기능입니다.
    • 상속을 통해 기존 클래스를 확장하고, 메서드 오버라이딩과 super 키워드를 사용하여 더 강력하고 유연한 클래스를 설계할 수 있습니다.
  • 다음 포스팅에서는 자바의 제어자에 대해서 먼저 정리할 예정입니다.
profile
일 때문에 포스팅은 잠시 쉬어요 ㅠ 바쁘다 바빠 모두들 화이팅! // Machine Learning (AI) Engineer & BackEnd Engineer (Entry)

0개의 댓글