반응형

 

Welcome Page를 만들어보겠습니다. 프로그램이 실행될 때, 가장 먼저 실행되어 출력되는 Welcome page를 만들기 위해서는
src 폴더 / resources / static으로 접근하여 static에 index.html file을 생성합니다. (오른쪽 우클릭 후 나오는 file 생성 메뉴)

생성 후 출력물을 띄우기 위해서 간단한 html 코드를 작성 후 HelloSpringApplication을 실행 하고 , localhost:8080로 접속하면 작성된 Hello가 출력되는 지를 확인할 수 있습니다.

💡 Spring Boot가 제공하는 Welcome Page 기능


Spring은 실행 시 static폴더 내에 있는 index.html파일을 찾아서 동작하는 기능을 제공합니다.
이 때의 static에 있는 index.html은 그냥 화면에 입력된 마크다운 언어를 띄어주기만 하는 정적페이지인데,
템플릿 엔진을 사용하면 해당 파일을 동적으로 변화시킬 수가 있습니다.
- 스프링 공식 튜토리얼 : https://spring.io/guides
- 스프링 부트 메뉴얼 : https://docs.spring.io/spring-boot/docs/current/reference/html/

 

 

Spring Boot Reference Documentation

The reference documentation consists of the following sections: Legal Legal information. Getting Help Resources for getting help. Documentation Overview About the Documentation, First Steps, and more. Getting Started Introducing Spring Boot, System Require

docs.spring.io

 

hello.hellospring 안에 controller 패키지를 생성 후 HelloController 클래스를 생성

 

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {

    @GetMapping("hello")
    public String hello(Model model) {
    
        model.addAttribute("data","Hello!!");
        return "hello";
        
    }
}

 

먼저 package와 class 사이 공간에 @controller를 입력해주면 자동으로 상단에 import org.springframework.stereotype.Controller; 해당문구가 입력되며 Controller가 import 됩니다.

 

웹 브라우저에서 http://localhost:8080/hello로 입력하면 스프링 부트는 톰캣이라는 웹 서버를 내장하고 있는데,
그 서버에서 입력된 주소를 스프링으로 전달해주는데, helloController 클래스 내부에 작성된 @GetMapping(”hello”)로 인해 hello가 url에 매칭을 확인합니다.
public String hello(Model model) { model.addAttribute("data","Hello!!"); return "hello"; } → 해당 메서드를 실행하게 됩니다.

이 후 스프링이 Model을 생성하여 model에는 data:hello!! 담아두었습니다. return은 resources안에 templates내에 이름이 “hello”인 파일을 실행하게됩니다. 즉, templates/hello.html을 실행하게 되는 것입니다. ${data} → model에서 넘겨진 key값이다 (=hello!!)

 

💡 ViewResolver (뷰 리졸버)

View Resolver(뷰 리졸버)는 웹 애플리케이션에서 사용되는 MVC 패턴에서 컨트롤러가 처리한 결과를 어떤 뷰(View)로 보여줄지를 결정하는 역할을 합니다.

일반적으로 MVC 패턴에서 컨트롤러는 비즈니스 로직을 처리한 후에 클라이언트에게 결과를 보여줄 뷰를 선택해야 합니다.
이때 View Resolver는 컨트롤러의 처리 결과와 매핑되는 뷰를 찾아주는 역할을 수행합니다.

View Resolver는 컨트롤러가 반환한 뷰의 이름을 기반으로 실제 뷰 객체를 찾아내는 과정을 수행합니다.
이를 통해 컨트롤러와 뷰 사이의 강한 결합을 피하고, 유연한 뷰 선택을 가능하게 합니다.
또한 View Resolver는 뷰의 경로나 포맷에 대한 설정을 담당하여 개발자가 뷰의 경로를 하드코딩하는 것을 피할 수 있도록 합니다.

일반적으로 View Resolver는 설정 파일에 등록되며, 컨트롤러에서 반환하는 뷰의 이름을 기반으로 해당하는 뷰 객체를 찾아내는 방식으로 동작합니다.
View Resolver는 컨트롤러와 뷰 간의 인터페이스 역할을 수행하여, 컨트롤러의 처리 결과를 적절한 뷰로 매핑하여 클라이언트에게 보여줄 수 있도록 도와줍니다.

Spring Framework에서는 다양한 유형의 View Resolver를 제공하며, 개발자는 필요에 따라 해당 View Resolver를 선택하고 설정할 수 있습니다.
이를 통해 Spring MVC에서는 컨트롤러와 뷰 간의 느슨한 결합을 유지하면서 유연하고 확장 가능한 웹 애플리케이션을 개발할 수 있습니다.

 

작성한 project file을 터미널에 ./gradlew.bat build를 통해 빌드 후 실행을 확인합니다.
빌드 폴더 생성 시에는 경로로 설정 → PS D:\backend\Spring\hello-spring>./gradlew.bat build하면 빌드폴더가 생성되고
이 후 빌드를 지우고 싶으면 다시 이전 경로로 이동 후 ./gradlew build clean을 입력해주면 build 폴더 내에 build 되었던 데이터가 지워지게 됩니다.

 

 

이 링크를 통해 구매하시면 제가 수익을 받을 수 있어요. 🤗
인프런(김영한) - 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

https://inf.run/SGi5S

728x90
반응형

 

💡 Java 11 설치하고 통합개발환경도구로는 intelliJ 또는 Eclipse를 설치한다.

 

Project는 개발에 필요한 라이브러리를 불러와주고 빌드 라이프사이클까지 관리해주는 툴인 Gradle or Maven 둘 중에 하나를 골라서 사용하는데 일반적으로 Gradle을 사용해서 진행합니다.

언어는 JAVA를 선택한 후 진행하고, SpringBoot는 버전을 선택하는데 뒤에 SNAPSHOT(아직 만들고 있는 것) 이나 M2 (정식 릴리즈버전이 아님) 가 붙은 임시 버전을 제외하고 아무 버전이나 사용해도 무방합니다.
3.0 이상 부터는 자바 17이상 지원하기에 자바를 또 설치하셔야 합니다. 2.7.10 으로 선택해서 진행해도 괜찮습니다.

Group - 기업 도메인 명을 작성하나, 연습용으로는 아무거나 괜찮습니다.
Artifact - 릴리즈 될때의 결과물인데 프로젝트명과 유사한 의미입니다.
Dependencies - 프로젝트 시작 시 어떤 라이브러리를 불러와서 사용할 것인가를 고르는 것입니다.
Spring Web과 Thymeleaf를 2개의 라이브러리를 골라서 선택합니다.
Generate로 다운로드를 받은 후 압축을 푼 후 intelliJ에서 build.gradle 파일을 오픈합니다.

 

src폴더 안에 main폴더와 test폴더가 기본적으로 나누어져서 구조가 이루어져 있다.

 

 

이 링크를 통해 구매하시면 제가 수익을 받을 수 있어요. 🤗
인프런(김영한) - 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

https://inf.run/SGi5S

728x90
반응형
💡 Object 클래스란?


Java에서 Object는 모든 클래스의 최상위 부모 클래스입니다. 모든 클래스는 암묵적으로 Object 클래스를 상속받습니다.
Object 클래스는 Java의 기본적인 기능과 메서드를 제공하며, 모든 객체가 가져야 할 공통 동작을 정의합니다.

java에서 하나의 클래스를 만들면 기본적으로 생략된 코드들이 있다

① default packgae - ex) import.java.lang.*;
② 최상위 클래스 - ex) public class A extends Object ⇒ java.lang.Object
③ default 생성자 - ex) public A() { super(); }

 

https://yeomboyeon.tistory.com/67

 

💡 Object 클래스내의 자주 쓰이는 메서드

 

Object 클래스의 주요 메서드로는 다음과 같은 것들이 있습니다:

  1. equals(): 객체의 동등성을 비교하는 메서드입니다. 기본적으로는 객체의 주소 비교를 수행하지만, 필요에 따라 재정의하여 객체의 내용 비교를 수행할 수 있습니다.
  2. hashCode(): 객체의 해시 코드 값을 반환하는 메서드입니다. 객체의 동등성을 검사하는데 사용될 수 있습니다.
  3. toString(): 객체를 문자열로 표현하는 메서드입니다. 기본적으로는 클래스명과 해시 코드를 반환하며, 필요에 따라 재정의하여 객체의 정보를 적절히 표현할 수 있습니다.
  4. getClass(): 객체의 클래스 정보를 반환하는 메서드입니다. Class 클래스의 인스턴스를 반환합니다.
  5. clone(): 객체를 복제하는 메서드입니다. 객체의 얕은 복사를 수행합니다.
  6. finalize(): 객체가 소멸될 때 호출되는 메서드입니다. Java에서는 가비지 컬렉터가 객체를 수거하기 전에 이 메서드를 호출합니다.

Object 클래스의 존재는 모든 객체가 공통적인 기능과 동작을 가지도록 하여 객체 지향 프로그래밍의 기본 원칙을 준수할 수 있도록 도와줍니다. 또한, 다형성을 지원하고 객체를 일반적인 형식으로 다룰 수 있도록 합니다.

 

        //B클래스 

        public class B extends Object {
            public void printGo() {
                System.out.println("나는 B입니다.");
            }
        }


        //A클래스 
        public class A extends Object{ //생략된 기본 최상위클래스 Object와 상속관계

            public A(){  //생략된 A클래스의 default 생성자
                super();
            }

            public void display() {
                System.out.println("나는 A 클래스 입니다.");
            }
            public void printGo() {
                System.out.println("나는 A 클래스 입니다.");
            }

        }

        //main 메서드 클래스
        import Poly.A;
        import Poly.B;

        public class ObjectPolyArg {
            public static void main(String[] args) {

                A a = new A();
                display(a);  // display 메서드에 A 객체 전달
                B b = new B();
                display(b);  // display 메서드에 B 객체 전달

            }

            private static void display(A a) {
                a.printGo();
            }
            private static void display(B b) {
                b.printGo();
            }
        }

 

display() 메서드에 인수로 A a를 전달하는 이유는 메서드 내부에서 A 클래스에 정의된 printGo() 메서드를 호출하기 위해서입니다.

만약 display() 메서드에 인수로 a만 전달하면, 컴파일러는 해당 인수의 타입을 알 수 없기 때문에 어떤 메서드를 호출해야 할지 판단할 수 없습니다. 따라서 인수에 타입을 명시하여 컴파일러에게 전달된 객체의 타입을 알려주어야 합니다.

이렇게 타입을 명시함으로써 컴파일러는 A a가 A 클래스의 인스턴스임을 알 수 있고, 따라서 A 클래스에 정의된 메서드인 printGo()를 호출할 수 있게 됩니다. 타입의 명시는 컴파일러가 올바른 메서드 호출을 검증하고 실행 가능한 코드를 생성하는 데 도움을 줍니다.

728x90
반응형
Q. 서로 다른 동작을 가지는 클래스를 상속관계로 만들어서 동작을 시켜야한다고 가정해보자
서로 다른 동작의 클래스도 공통 기능을 만들어서 상속구조로 사용 가능?


https://velog.io/@mmy789/

 

상위클래스가 일반클래스인 클래스와의 상속관계에서는 하위클래스에서 상위클래스로 객체를 생성해서 사용할 때, 각각의 클래스들의 담겨져 있는 메서드를 사용할때 재정의(Override)를 해야하는 것은 아닙니다 ⇒ 다형성이 보장되진 않습니다.

상위클래스가 추상클래스인 클래스와의 상속관계에서는 추상클래스 내에 생성된 추상메서드에 따라 하위클래스에서 꼭 재정의(Override)를 해야합니다. 재정의를 하게 만들어서 다형성을 보장할 수는 있지만, 상위클래스는 구현클래스를 가질 수 있어서 이로 인해 하위클래스가 오동작할 수 있습니다.
재정의를 하게 만들어서 다형성을 보장할 수는 있지만, 상위클래스는 구현클래스를 가질 수 있어서 이로 인해 하위클래스가 오동작할 수 있습니다. ⇒ 추상메서드와 일반구현메서드가 서로 다른 동작을 가지는 클래스이기 때문

이렇게 서로 다른 동작(=메서드)을 가지는 클래스를 상속관계로 만들어서 동작을 시켜야 할 때에는 클래스가 아닌 인터페이스를 선언하여 사용해야 합니다.

 

❓ 인터페이스란 ?

객체 지향 프로그래밍에서 클래스와 관련된 동작(메서드)의 집합을 정의하는 추상화된 형식이며, 클래스에서 구현해야 하는 메서드들의 목록을 정의하는 역할을 합니다. 다른 클래스들이 특정 동작을 구현하도록 규약을 제공하며, 클래스 간의 계약(contract)을 정의하는 역할을 합니다.

* interface 문법
  interface 인터페이스 이름  {
        public static final 타입 상수이름 = 값;
        public abstract 메서드이름(매개변수 목록);
  }

 

인터페이스도 일종의 추상클래스라고 볼 수 있지만, 추상클래스와 달리 추상 메서드만을 포함하며, 일반 메서드, 멤버 변수, 생성자를 가질 수 없습니다. 클래스에서 인터페이스를 구현할 때는 모든 추상 메서드를 반드시 구현해야 합니다.

인터페이스는 interface 키워드를 사용하여 정의되며, 메서드의 시그니처(이름, 매개변수, 반환값)만을 선언하고, 구현 내용을 가지지 않습니다. 또한, 추상메서드와 final static 상수만 가질 수 있습니다. 클래스는 인터페이스를 implements 키워드를 사용하여 구현할 수 있으며, 인터페이스에 정의된 모든 메서드를 반드시 구현해야 합니다.

 

인터페이스는 구현메서드가 없기 때문에 객체 생성이 불가능하지만 Upcasting으로 상위클래스의 역할은 할 수 있습니다.인터페이스는 다음과 같은 특징을 갖습니다:

  1. 추상 메서드: 인터페이스는 추상 메서드만을 가지므로, 메서드의 구현 내용이 없습니다. 따라서, 인터페이스를 구현하는 클래스에서는 인터페이스에 정의된 메서드를 반드시 구현해야 합니다.
  2. 다중 상속: 클래스는 하나의 클래스만 상속할 수 있지만, 인터페이스는 여러 개의 인터페이스를 동시에 구현할 수 있습니다. 이를 통해 다중 상속의 일부 기능을 구현할 수 있습니다.
  3. 계약: 인터페이스는 클래스들 사이의 계약(Contract)을 정의하는 역할을 합니다. 클래스가 인터페이스를 구현한다는 것은 인터페이스에 정의된 메서드를 반드시 구현한다는 의미이며, 이를 통해 클래스들 간의 일관성을 유지할 수 있습니다.
  4. 다형성: 인터페이스를 사용하면 여러 클래스들을 하나의 인터페이스 타입으로 참조할 수 있으며, 이를 통해 다형성의 특징을 활용할 수 있습니다.
728x90
반응형
❓ 다형성(Polymorphism) 이란 ?

 

동일한 메시지(메서드 호출)에 대해 서로 다른 객체가 다르게 동작하는 능력(message pholymorphism)을 말합니다.
다형성은 한 가지 타입 또는 인터페이스를 여러 개의 구현체가 가질 수 있도록 함으로써 유연하고 확장 가능한 코드를 작성할 수 있게 합니다.

다형성은 상속과 관련하여 사용되며, 부모 클래스와 그 자식 클래스들 간에 동일한 메서드 이름을 가지고 있지만 각각의 클래스에서 다른 구현을 가지도록 하는 것을 의미합니다.
다형성은 같은 타입으로 선언된 객체가 실제로 실행 시에는 여러 다른 타입의 객체로 동작할 수 있게 합니다.

다형성은 다음과 같은 방식으로 구현됩니다:

  1. 업캐스팅(Upcasting): 자식 클래스의 인스턴스를 부모 클래스의 참조 변수로 참조하는 것을 말합니다. 부모 클래스의 참조 변수를 통해 자식 클래스의 객체에 접근할 수 있습니다. 업캐스팅을 통해 여러 개의 자식 클래스를 하나의 부모 클래스 타입으로 관리할 수 있습니다.
  2. 메서드 오버라이딩(Method Overriding): 자식 클래스에서 부모 클래스의 메서드를 재정의하여 자식 클래스에서 특화된 구현을 제공합니다. 부모 클래스의 메서드를 자식 클래스에서 동일한 이름으로 재정의하면, 실행 시에는 실제 객체의 타입에 맞는 메서드가 호출됩니다.
  3. 다형적 변수(Polymorphic Variables): 부모 클래스의 참조 변수를 사용하여 여러 자식 클래스의 객체를 참조할 수 있습니다. 이렇게 다형적 변수를 사용하면 실행 시에 실제 객체의 타입에 따라 다른 동작을 수행할 수 있습니다.

다형성은 코드의 유연성과 재사용성을 높여주며, 객체 지향 프로그래밍의 핵심 원칙 중 하나인 "프로그램을 작성할 때는 구체적인 타입보다는 추상적인 타입에 의존하라(Depend upon abstractions)"를 실현하는 방법 중 하나입니다.

 

https://kadosholy.tistory.com/99

 

 

        //Cat 클래스 (자식)
        public class Cat extends Animal {
                public void eat() {
                    System.out.println("고양이처럼 밥 먹는다");
                }
        }

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

            public void eat() {
                System.out.println("강아지처럼 먹어보자");
            }
        }

        //Animal 클래스 (부모)
        public class Animal {
            public void eat() {
                System.out.println("동물처럼 먹다");
            }
        }

        //Override 클래스 (메인)
        public static void main(String[] args) {
        /*
        Upcastiong(업캐스팅) -> 만약 다른 사람이 Dog클래스를 java 소스코드를 주지 않고, 
        class 파일만 주었을 때, Dog 클래스로 선언하기 어려움

        Animal <---> Dog.class(o) Animal 클래스가 Dog클래스와 상속관계에 있다는 것을 
        알고있다는 가정하에 Override 통해 eat()을 재 정의 할 수 있게 됩니다.
        */
                Animal ani = new Dog();
                ani.eat();
        // Animal ----실행시점에서 메서드가 결정되는 것(동적바인딩)---> Dog
        // 작성 시에는 eat()가 Animal에 속해있는 것이라고 생각되어 에러가 나지 않았지만, 실행과 동시에 Dog의 eat()이 실행되게 됩니다 / 이를 동적바인딩이라고 합니다.
                System.out.println("ani = " + ani);
            }
        }

앞서 업캐스팅과 동적바인딩을 설명할 때 , 사용했던 코드로 다형성을 설명해보면, 부모클래스 (Animal)이 먹다(eat())
메서드를 자식클래스인 Dog와 Cat에게 메세지를 보내면 자식 클래스가 반응을 하는데, 두 자식 클래스에서 eat() 메서드가 개와 고양이로 다르기 때문에 서로 다르게 반응을 하게 됩니다.

다형성을 적용하기 위해서는 Upcasting으로 객체를 생성 상속 관계로 되어 있어야 하며, 재 정의가 되어있고, 메모리에서 동적 바인딩이 되어있는 관계여야 가능하다.
상위클래스가 동일한 메세지로 하위 클래스를 서로 다르게 동작시키는 객체지향 원리 (=message polymorphism)

컴파일 시점에선 eat()가 Animal내의 eat() , 실행시점에서 호출될 메서드가 결정되는 바인딩 = 동적바인딩
-> 동적바인딩이 일어나야 eat()라는 메서드가 Animal것인지 Dog것인지 알 수 있다.

 

💡 다형성(message polymorphism)의 전제조건

1. 상속관계    2. Override(재정의)    3. Upcasting(업캐스팅)   4. 동적 바인딩

 

💡 다형성 활용 - 다형성 인수란 ?

다형성 인수(Polymorphic Parameters)란, 메서드나 함수의 매개변수(parameter)를 다형성(polymorphism)을 활용하여 여러 타입의 객체를 전달할 수 있는 것을 말합니다. 이를 통해 코드의 재사용성과 유연성을 높일 수 있습니다.

 

        public void makeShape(Shape shape) {
            // 도형을 처리하는 로직
            shape.draw();
        }

        Circle circle = new Circle();
        Triangle triangle = new Triangle();
        Rectangle rectangle = new Rectangle();

        makeShape(circle);     // Circle 객체 전달
        makeShape(triangle);   // Triangle 객체 전달
        makeShape(rectangle);  // Rectangle 객체 전달

 

위의 코드에서 makeShape 메서드는 Shape 타입의 매개변수 shape를 받습니다. 이 매개변수는 다형성 인수로, Shape 클래스를 상속한 여러 도형 클래스의 인스턴스를 전달할 수 있습니다. 예를 들면, Circle, Triangle, Rectangle 클래스가 Shape 클래스를 상속한다고 가정해보겠습니다.

위의 코드에서 makeShape 메서드에 각각의 도형 객체를 전달하고 있습니다. 이 때, 전달되는 객체는 각자의 실제 타입인 Circle, Triangle, Rectangle 이지만, 메서드 내부에서는 Shape 타입으로 참조되고 처리됩니다. 이는 다형성의 개념을 활용한 예시로서, 동일한 메서드를 여러 타입의 객체에 대해 재사용할 수 있음을 보여줍니다.

다형성 인수는 코드의 유연성과 확장성을 제공하며, 객체지향 프로그래밍에서 중요한 개념 중 하나입니다.

instanceof 연산자 : instanceof 연산자는 객체의 타입을 확인하기 위해 사용되는 연산자 사용 문법
[객체] instanceof [타입]

instanceof를 사용하여 특정 객체가 특정 클래스의 인스턴스인지를 확인할 수 있습니다.

        Shape shape = new Circle();

        if (shape instanceof Circle) {
            System.out.println("shape은 Circle의 인스턴스입니다.");
        } else if (shape instanceof Rectangle) {
            System.out.println("shape은 Rectangle의 인스턴스입니다.");
        } else {
            System.out.println("shape은 Circle 또는 Rectangle의 인스턴스가 아닙니다.");
        }


위의 코드에서 makeShape 메서드는 Shape 타입의 매개변수 shape를 받고, shape 객체의 타입을 instanceof 연산자를 사용하여 확인합니다. 이후 해당하는 타입으로 캐스팅하여 각각의 타입에 맞는 처리 로직을 수행합니다. instanceof 연산자는 주어진 객체가 해당 타입의 인스턴스인지를 불리언(Boolean) 값으로 반환합니다. 만약 객체가 해당 타입의 인스턴스이면 true를 반환하고, 그렇지 않으면 false를 반환합니다.

instanceof 연산자는 객체의 상속 관계나 인터페이스 구현 여부를 확인할 때 주로 사용됩니다. 타입 검사를 통해 객체의 동적인 타입을 파악하여 적절한 동작을 수행할 수 있습니다. 다형성과 함께 사용하면 유연하고 확장 가능한 코드를 작성할 수 있습니다.

💡 다형성 활용 - 다형성 배열(상위타입 배열)이란?

 

다형성배열이란 ? 다형성 개념을 배열에 적용한 것을 의미합니다. 성 배열은 여러 타입(서로 다른 타입)의 객체를 하나의 배열에 저장할 수 있는 특징을 갖고 있습니다.

일반적으로 배열은 동일한 타입의 객체들만 저장할 수 있지만, 다형성 배열은 부모 클래스를 상속받은 서브 클래스들을 모두 저장할 수 있습니다. 이를 통해 서로 다른 타입의 객체를 하나의 배열에 함께 저장하고 관리할 수 있습니다. 부모클래스 타입의 배열은 자식클래스 타입을 저장하는 것이 가능합니다.

728x90
반응형

이전에는 데이터의 상태정보에 초점을 맞춰 DTO, VO 클래스 위주로 데이터를 다루었다면, 행위(동작) 정보를 초점에 맞춰서 클래스와 클래스를 설계(상속)하는 방법을 알아보겠습니다.


 

수평적 구조로 설계하다보면 Dog와 Cat의 공통적으로 할 수 있는 동작은 eat(먹다) 라는 같은 기능을 하는 동작의 중복이 발생합니다.
동물들에게는 eat라는 중복기능이 나올 확률이 높습니다.

 

        class Animal {
          // 부모 클래스 멤버
        }


        class Dog extends Animal {
          // 자식 클래스 멤버
        }


        Dog dog = new Dog();
        Animal animal = dog; // Upcasting


        Animal animal = new Dog(); // Upcasting


        if (animal instanceof Dog) {

          Dog dog = (Dog) animal; // Downcasting
          // dog 변수를 통해 animal이 Dog 클래스의 멤버에 접근

        }

 

https://yeomboyeon.tistory.com/m/63

 

🎈 Upcasting(업캐스팅 / 자동형변환) 이란 ?

업캐스팅은 부모 클래스 타입으로 자식 클래스의 객체를 참조하는 것을 말합니다.
업캐스팅을 사용하는 이유는 다형성(Polymorphism)을 활용하기 위함입니다. 부모 클래스는 자식 클래스의 공통된 특징과
기능을 포함하고 있으므로, 업캐스팅을 통해 부모 클래스 타입으로 자식 클래스의 객체를 다룰 수 있게 됩니다.
이로써 코드의 유연성과 확장성을 높일 수 있습니다. 업캐스팅은 런타임에 동적으로 객체의 실제 타입을
결정할 수 있기 때문에 다양한 자식 클래스의 객체를 부모 클래스 타입으로 처리할 수 있습니다.

 

💡 업캐스팅 문법 → 상위 클래스타입 인스턴스 변수 = new 하위클래스();

 

Animal x = new Dog();

 

→ 객체로의 생성은 Dog()이지만 Animal의 타입으로 받습니다. 둘은 상속관계이기때문에 가능합니다. (하위가 상위로 들어가는 것은 자동!)
부모가 자식을 가리키는 객체 생성 방법 → 하위 클래스의 동작을 알 수 없을때는, 부모타입으로 객체를 생성할 수 밖에 없기때문에 자주 사용됩니다.

 

🎈 Downcasting(다운캐스팅 / 강제형변)이란 ?

다운캐스팅은 업캐스팅된 객체를 다시 원래의 자식 클래스 타입으로 변환하는 것을 말합니다.
다운캐스팅은 주로 다형성을 통해 업캐스팅된 객체가 실제로 어떤 자식 클래스의 객체인지 확인하고,자식 클래스에 고유한 메서드나 속성에 접근하기 위해 사용됩니다.
다운캐스팅은 정확한 타입의 메서드나 속성을 사용할 수 있도록 객체를 변환해주는 역할을 합니다.
다운캐스팅은 업캐스팅된 객체를 다시 자식 클래스 타입으로 형변환하여 사용하는 것이기 때문에
정확한 타입 체크가 필요하며, 올바른 타입이 아닌 경우에는 ClassCastException이 발생할 수 있습니다.

 

💡 다운캐스팅 문법하위클래스의 타입 다운캐스팅된 객체를 저장할 변수 = (하위클래스의 타입) 상위클래스의 객체

 

다운캐스팅은 주의해야 할 점이 있습니다. 만약 다운캐스팅을 시도하는 객체가 실제로 해당 하위 클래스의 인스턴스가 아니라면,ClassCastException이 발생할 수 있습니다. 따라서 다운캐스팅을 수행하기 전에 항상 해당 객체가 정말로 하위 클래스의 인스턴스인지를 확인하는 것이 좋습니다.
이를 위해 instanceof 연산자를 사용할 수 있습니다.

 

instanceof 연산자 : instanceof 연산자는 객체의 타입을 확인하기 위해 사용되는 연산자 사용 문법 : [객체] instanceof [타입]

 

업캐스팅은 다양한 자식 클래스를 부모 클래스의 타입으로 다룰 수 있도록 하고, 다운캐스팅은 업캐스팅된 객체를 원래의 자식 클래스 타입으로 형변환하여 자식 클래스에 고유한 기능에 접근할 수 있도록 합니다.

728x90

+ Recent posts