본문 바로가기

Java

[자바의정석/7] 객체지향에 대하여

728x90
반응형

상속(Inheritance)

 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것.

  • 적은 양의 코드로 새로운 클래스를 작성할 수 있고 공통적으로 관리할 수 있다 -> 추가 및 변경이 매우 용이
  • 코드의 재사용성을 높이고 코드의 중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여

 자손 클래스는 조상 클래스의 모든 멤버를 상속 받으므로 항상 조상 클래스보다 같거나 많은 멤버를 갖는다. 그래서 상속을 받는다는 것은 조상 클래스를 확장(extends)한다는 의미로 해석할 수 있다.

  •  생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
  •  자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.

super

자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조 변수이다. 멤버변수와 지역변수의 이름이 같을 때 this를 붙여서 구별했듯이 상속받은 멤버와 자신의 멤버와 이름이 같을 때는 super를 붙여 구별할 수 있다. 

Object 클래스를 제외한 모든 클래스의 생성자 첫 줄에 생성자, this() 또는 super()를 호출해야 한다. 그렇지 않으면 컴파일러가 자동적으로 super()를 생성자의 첫 줄에 삽입한다.
class Tv {
	boolean power;
    int channel;
    
    void power() { power = !power;}
    void channelUp() {++channel;}
    void channelDown() { --channel;}
}
class CaptionTv extends Tv {
	boolean caption;
    void displayCaption(String text) {
    	if(caption) {
        	System.out.println(text);
        }
    }
}
class CaptionTvTest {
	public static void main(String args[]) {
    	CaptionTv ctv = new CaptionTv();
        ctv.channel = 10;					//조상 클래스로부터 상속받은 멤버
        ctv.channelUp();
        System.out.println(ctv.channel);
        ctv.displayCaption("Hello, world");
        ctv.caption = true;
        ctv.displayCaption("Hello, world");
    }
}
//자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다.

제어자(modifier)

접근 제어자 - public, protected, default, private
그 외 - static, final, abstract, native, transient, synchronized, volatile, strictfp

private - 같은 클래스 내에서만 접근이 가능하다.
default - 같은 패키지 내에서만 접근이 가능하다.
protected - 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능하다.
public - 접근 제한이 전혀 없다.
제어자 대상 의미
static
- 클래스의
- 공통적인
멤버변수 - 모든 인스턴스에 공통적으로 사용되는 클래스 변수가 된다.
- 클래스 변수는 인스턴스를 생성하지 않고도 사용 가능하다.
- 클래스가 메모리에 로드될 때 생성된다.
메서드 - 인스턴스를 생성하지 않고도 호출이 가능한 static 메서드가 된다.
- static 메서드 내에서는  인스턴스 멤버들을 직접 사용할 수 없다.
final
- 마지막의
- 변경 안되는
클래스 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다. 그래서 final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다.
메서드 변경될 수 없는 메서드, final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다.
멤버변수 변수 앞에 fianl이 붙으면, 값을 변경할 수 없는 상수가 된다.
지역변수
abstract
- 추상의
- 미완성의
클래스 클래스 내에 추상 메서드가 선언되어 있음을 의미한다.
메서드 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다.

 

class StaticExample {
    static int staticVar = 10; // static 변수

    static void staticMethod() { // static 메서드
        System.out.println("이것은 static 메서드입니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(StaticExample.staticVar); // 인스턴스 생성 없이 static 변수 접근
        StaticExample.staticMethod(); // 인스턴스 생성 없이 static 메서드 호출
    }
}
final class FinalClass { // final 클래스
    final void finalMethod() { // final 메서드
        System.out.println("이 메서드는 오버라이딩될 수 없습니다.");
    }
}

class Example {
    final int finalVar = 100; // final 변수

    void method() {
        // finalVar = 200; // 오류 발생 - final 변수는 값을 변경할 수 없음
    }
}
abstract class AbstractClass { // abstract 클래스
    abstract void abstractMethod(); // abstract 메서드
}

class ConcreteClass extends AbstractClass {
    @Override
    void abstractMethod() {
        System.out.println("추상 메서드의 구현");
    }
}

public class Main {
    public static void main(String[] args) {
        ConcreteClass obj = new ConcreteClass();
        obj.abstractMethod(); // 추상 메서드의 구현 호출
    }
}

다형성(polymorphism)

어떤 객체의 속성이나 기능이 상황에 따라 여러 가지 형태를 가질 수 있는 성질
ex) 메서드 오버라이딩, 메서드 오버로딩

[ 오버라이딩(overriding) ]

조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것.

  • 자손 클래스에서 오버라이딩하는 메서드는 조상 클래스의 메서드와 이름이 같아야 한다.
  • 매개변수가 같아야 한다.
  • 반환타입이 같아야 한다.
class Animal {
    // 부모 클래스의 메서드
    public void sound() {
        System.out.println("동물 소리");
    }
}

class Dog extends Animal {
    // 오버라이딩된 메서드
    @Override
    public void sound() {
        System.out.println("멍멍");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Animal();
        myAnimal.sound(); // "동물 소리" 출력

        Animal myDog = new Dog();
        myDog.sound(); // "멍멍" 출력, 오버라이딩된 메서드 호출
    }
}

[ 오버로딩 ]

자바에서는 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있더라도 매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메서드를 정의할 수 있다. 같은 이름의 메서드를 여러 개 정의하는 것을 메서드 오버로딩이라 한다.

  • 메서드 이름이 같아야 한다.
  • 매개변수의 개수 또는 타입이 달라야 한다.
class OverloadingExample {
    // 매개변수가 없는 메서드
    void display() {
        System.out.println("매개변수 없음");
    }

    // 매개변수가 하나인 메서드
    void display(int a) {
        System.out.println("정수 매개변수: " + a);
    }

    // 매개변수의 타입이 다른 메서드
    void display(String a) {
        System.out.println("문자열 매개변수: " + a);
    }

    // 매개변수의 개수가 다른 메서드
    void display(int a, int b) {
        System.out.println("두 개의 정수 매개변수: " + a + ", " + b);
    }
}

public class Main {
    public static void main(String[] args) {
        OverloadingExample obj = new OverloadingExample();

        obj.display();              // "매개변수 없음"
        obj.display(1);             // "정수 매개변수: 1"
        obj.display("테스트");        // "문자열 매개변수: 테스트"
        obj.display(1, 2);          // "두 개의 정수 매개변수: 1, 2"
    }
}

추상화

[ 추상 클래스 ]

클래스를 설계도에 비유한다면, 추상 클래스는 미완성 설계도에 비유할 수 있다.

추상 클래스 자체로는 클래스로서의 역할을 다 못하지만 어느 정도 틀을 갖춘 상태에서 시작하는 것이 좋기 때문에 사용한다.

 

[ 추상 메서드 ]

메서드는 선언부와 구현부로 구성되어 있다. 선언부만 작성하고 구현부는 작성하지 않은 채로 남겨 둔 것이 추상 메서드이다.

이와 같이 미완성 상태로 남겨 놓는 이유는 메서드의 내용이 상속받는 클래스에 따라 달라질 수 있기 때문이다.

// 추상 클래스
abstract class Animal {
    // 추상 메서드 (구현되지 않음)
    abstract void sound();

    // 일반 메서드
    void breathe() {
        System.out.println("숨을 쉽니다.");
    }
}

// 추상 클래스를 상속받는 하위 클래스
class Dog extends Animal {
    // 추상 메서드 구현
    @Override
    void sound() {
        System.out.println("멍멍");
    }
}

class Cat extends Animal {
    // 추상 메서드 구현
    @Override
    void sound() {
        System.out.println("야옹");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound(); // 멍멍
        dog.breathe(); // 숨을 쉽니다.

        Cat cat = new Cat();
        cat.sound(); // 야옹
        cat.breathe(); // 숨을 쉽니다.
    }
}

인터페이스

인터페이스는 일종의 추상 클래스이다. 오직 추상메서드와 상수만을 멤버로 가질 수 있으며, 그 외의 다른 어떠한 요소도 허용하지 않는다.

  • 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.
  • 모든 멤버변수는 public abstract 이어야 하며, 이를 생략할 수 있다.
    단, static 메서드와 default 메서드는 예외(JDK1.8~)

[ 인터페이스 장점 ]

  • 개발 시간을 단축시킬 수 있다.
  • 표준화가 가능하다.
  • 서로 관계없는 클래스들에게 관계를 맺어줄 수 있다.
  • 독립적인 프로그래밍이 가능하다.
// 인터페이스 선언
interface Animal {
    void sound(); // 추상 메서드
}

// 인터페이스 구현
class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("멍멍");
    }
}

class Cat implements Animal {
    @Override
    public void sound() {
        System.out.println("야옹");
    }
}

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

        dog.sound(); // "멍멍" 출력
        cat.sound(); // "야옹" 출력
    }
}

 

728x90
반응형