KDT/Java

231214 Java

001cloudid 2023. 12. 14. 17:42
728x90

https://docs.oracle.com/en/java/javase/21/docs/api/index.html

상속

상속 예시

package inheritance_polymorphism;

//Customer 클래스 구현

 

 

public class Customer {

//멤버 변수

protected int cId; //고객ID

protected String cName; //고객 이름

protected String cGrade; //고객 등급

int point; //포인트

double ratio; //적립 비율

 

//디폴트 생성자

public Customer() {

//기본등급

cGrade = "bronze"; //기본등급

ratio = 0.1; //보너스 포인트 기본 적립 비율

}

 

//보너스 포인트 적립, 지불 가격 계산 메소드

public int calPrice(int price) {

point += point * ratio; //보너스 포인트 계산

return price;

}

 

//고객 정보를 반환하는 메소드

public String show() {

return cName + "님의 등급은 " + cGrade + "이며, 포인트는 " + point + "입니다";

}

 

public int getcId() {

return cId;

}

 

public void setcId(int cId) {

this.cId = cId;

}

 

public String getcName() {

return cName;

}

 

public void setcName(String cName) {

this.cName = cName;

}

 

public String getcGrade() {

return cGrade;

}

 

public void setcGrade(String cGrade) {

this.cGrade = cGrade;

}

}

 

package inheritance_polymorphism;

//VIPCustomer 클래스 구현

 

//VIPCustomer 클래스는 Customer클래스를 상속 받음

public class VIPCustomer extends Customer{

private int aID; //VIP고객 상담원 아이디

double vRatio; //할인율

 

public VIPCustomer() {

cGrade = "VIP";

ratio = 0.05;

vRatio = 0.1;

}

 

public int getAID() {

return aID;

}

}

 

package inheritance_polymorphism;

 

public class CustomerTest1 {

 

public static void main(String[] args) {

Customer c1 = new Customer();

c1.setcId(1);

c1.setcName("상속");

c1.point = 1000;

System.out.println(c1.show());

 

System.out.println("-----------------------------------");

 

VIPCustomer c2 = new VIPCustomer();

c2.setcId(2);

c2.setcName("다형성");

c2.point = 10000;

System.out.println(c2.show());

 

}

 

}

 

상속에서 클래스 생성과 형 변환

하위 클래스가 생성될 때 상위 클래스의 생성자가 먼저 호출된다.

 

하위 클래스가 생성되는 과정

하위 클래스는 상위 클래스의 변수와 메소드를 사용할 수 있다.

상위 클래스를 상속받은 하위 클래스가 생성될 때는 상위 클래스가 먼저 호출된다.

상위 클래스가 호출될 때 상위 클래스의 멤버 변수가 메모리에 생성

 

super

super 예약어는 하위 클래스에서 상위 클래스로 접근할 때 사용함. 하위 클래스는 상위 클래스의 참조 값을 알고 있음.

이 참조 값을 가지고 있는 예약어가 super이고 상위 클래스의 생성자를 호출하는 데도 사용

상위 클래스
       ↑
하위 클래스
super가 상위 클래스를 가리킴

 

상위 클래스에 선언한 멤버 변수나 메서드를 하위 클래스에서 참조할 때도 super를 사용

 

상위 클래스로 묵시적 클래스 형 변환

하위 클래스의 인스턴스가 상위 클래스로 형 변환되는 과정이 묵시적으로 이루어짐

 

메소드 오버라이딩

상위 클래스 메소드 재정의

상위 클래스에 정의한 메소드가 하위 클래스에서 구현할 내용과 맞지 않을 경우 하위 클래스에서 이 메소드를 재정의할 수 있음, 이를 메소드 오버라이딩(method overriding)이라고 함.

오버라이딩을 하려면 반환형, 메소드 이름, 매개변수 개수, 매개변수 자료형이 반드시 같아야함.

그렇지 않으면 컴파일러는 재정의한 메소드를 기존 메소드와 다른 메소드로 인식함

@Override
접근 제어자 자료형 메소드명(매개변수1,매개변수2,...){
 return super.메소드명(매개변수1, 매개변수2, ...);
}

@Override 애노테이션은 이 메소드는 재정의된 메소드다 라고 컴퍼일러에 명확히 알려주는 역할을 함

 

묵시적 클래스 형 변환과 메소드 재정의

상속에서 상위 클래스와 하위 클래스에 같은 이름의 메소드가 존재할 때 호출되는 메소드는 인스턴스에 따라 결정,

선언한 클래스형이 아닌 생성된 인스턴스의 메소드를 호출하는 것임

이렇게 인스턴스의 메소드가 호출되는 기술을 '가상 메소드(virtual method)'라고 한다.

 

가상 메소드

클래스는 멤버 변수와 메소드로 이루어짐.

클래스를 생성하여 인스턴스가 만들어지면 멤버 변수는 힙 메모리에 위치하며,

메소드는 실행해야 할 명령 집합이기 때문에 인스턴스가 달라도 로직은 수행

같은 객체의 인스턴스를 여러 개 생성한다고 해서 메소드도 여러 개 생성되지 않는다.

 

가상메소드 원리는 가상 메소드 테이블이 만들어지고, 가상 메소드 테이블은 각 메소드 이름과 실제 메모리 주소가

짝을 이룸. 어떤 메소드가 호출되면 이 테이블에서 주소 값을 찾아서 해당 메소드의 명령을 수행

 

다형성

하나의 코드가 여러개 자료형으로 구현되어 실행되는 것을 의미

그림 1

            
그림 1과 같이 동물 클래스를 상속 받는 경우에는 동물 클래스에 메소드를 하나 정의하고 상속받는 클래스에 재정의함

package inheritance_polymorphism;

 

class Animal {

public void move() {

System.out.println("동물이 움직임");

}

}

class Human extends Animal {

public void move() {

System.out.println("사람이 두 발로 움직임");

}

}

 

class Dog extends Animal {

public void move() {

System.out.println("개는 네 발로 움직임");

}

}

 

class Bird extends Animal {

public void move() {

System.out.println("새는 날개로 움직임");

}

}

 

public class AnimalTest1 {

public static void main(String[] args) {

AnimalTest1 testA = new AnimalTest1();

testA.moveAnimal(new Human());

testA.moveAnimal(new Dog());

testA.moveAnimal(new Bird());

 

}

 

public void moveAnimal(Animal animal) {

animal.move();

}

 

 

 

 

}

그림 2. 다형성 1

AnimalTest1 클래스에 moveAnimal() 메소드를 생성함.

이 메소드는 어떤 인스턴스가 매개변수로 넘어와도 모두 Animal형으로 변환함

다형성의 장점
다른 동물이 새로 추가되면 Animal 클래스를 상속받아 모든 클래스를 Animal 자료형 하나로 쉽게 관리할 수 있을 것이다.

다형성을 활용한 프로그램의 확장성이다.

상위 클래스에서 공통 부분의 메소드를 제공하고, 하위 클래스에서는 그에 기반한 추가 요소를 덧붙여 구현하면

코드 양도 줄어들고 유지보수도 편리하다.

정리하자면, 다형성을 잘 활용하면 유연하면서도 구조화된 코드를 구현하고 확장성 있고 유지보수하기 좋다.

package polymorphism;

 

public class Customer {

//멤버 변수

protected int cId; //고객ID

protected String cName; //고객 이름

protected String cGrade; //고객 등급

int point; //포인트

double ratio; //적립 비율

int bPoint;

double bRatio;

 

public Customer() {

initCustomer();//고객 등급과 보너스 포인트 적립률 지정 함수 호출

}

 

public Customer(int cID, String cName) {

this.cId = cId;

this.cName = cName;

initCustomer();//고객 등급과 보너스 포인트 적립률 지정 함수 호출

}

 

private void initCustomer() {

cGrade = "Silver";

bRatio = 0.01;

}

 

public int calcPrice(int price) {

bPoint += price * bRatio;

return price;

}

 

public String show() {

return cName + "님 등급은 " + cGrade +" 보너스 포인트는 " + bPoint;

}

 

public int getcId() {

return cId;

}

 

public void setcId(int cId) {

this.cId = cId;

}

 

public String getcName() {

return cName;

}

 

public void setcName(String cName) {

this.cName = cName;

}

 

public String getcGrade() {

return cGrade;

}

 

public void setcGrade(String cGrade) {

this.cGrade = cGrade;

}

 

}

 

package polymorphism;

 

public class VIPCustomer extends Customer{

private int aId;

double sRatio;

 

public VIPCustomer(int cId, String cName, int aId) {

super(cId, cName);

cGrade = "VIP";

bRatio = 0.05;

sRatio = 0.1;

this.aId = aId;

}

 

public int calcPrice(int price) {

bPoint += price * bRatio;

return price - (int)(price * sRatio);

}

 

public String show() {

return super.show() + "담당 상담원은 " + aId;

}

 

public int getaId() {

return aId;

}

 

}

 

package polymorphism;

 

public class CustomerTest {

 

public static void main(String[] args) {

Customer c1 = new Customer();

c1.setcId(100);

c1.setcName("일번");

c1.bRatio = 1000;

System.out.println(c1.show());

System.out.println("------------------");

 

Customer c2 = new VIPCustomer(101,"이번", 10);

System.out.println(c2.show());

System.out.println("------------------");

 

System.out.println("----할인율과 보너스 포인트 계산----");

int price = 10000;

int c1Price = c1.calcPrice(price);

int c2Price = c2.calcPrice(price);

 

System.out.println(c1.getcName() +"님께서 " + c1Price + "원 지불");

System.out.println(c1.show());

System.out.println(c2.getcName() +"님께서 " + c2Price + "원 지불");

System.out.println(c2.show());

 

}

 

}

그림 3. 다형성 2

 

다형성 활용

배열과 함께 사용하면 여러 하위 클래스 자료형을 상위 클래스 자료형으로 한 번에 관리할 수 있음

package witharraylist;

 

public class Customer {

protected int customerID;

protected String customerName;

protected String customerGrade;

int bonusPoint;

double bonusRatio;

 

public Customer()

{

initCustomer();

}

 

public Customer(int customerID, String customerName){

this.customerID = customerID;

this.customerName = customerName;

 

initCustomer();

}

 

private void initCustomer()

{

customerGrade = "SILVER";

bonusRatio = 0.01;

}

 

public int calcPrice(int price){

bonusPoint += price * bonusRatio;

return price;

}

 

public String showCustomerInfo(){

return customerName + " 님의 등급은 " + customerGrade + "이며, 보너스 포인트는 " + bonusPoint + "입니다.";

}

 

public int getCustomerID() {

return customerID;

}

 

public void setCustomerID(int customerID) {

this.customerID = customerID;

}

 

public String getCustomerName() {

return customerName;

}

 

public void setCustomerName(String customerName) {

this.customerName = customerName;

}

 

public String getCustomerGrade() {

return customerGrade;

}

 

public void setCustomerGrade(String customerGrade) {

this.customerGrade = customerGrade;

}

}

 

package witharraylist;

 

public class VIPCustomer extends Customer{

private int agentID;

double saleRatio;

 

public VIPCustomer(int customerID, String customerName, int agentID){

super(customerID, customerName);

 

customerGrade = "VIP";

bonusRatio = 0.05;

saleRatio = 0.1;

this.agentID = agentID;

}

 

public int calcPrice(int price){

bonusPoint += price * bonusRatio;

return price - (int)(price * saleRatio);

}

 

public String showCustomerInfo(){

return super.showCustomerInfo() + " 담당 상담원 번호는 " + agentID + "입니다";

}

 

public int getAgentID(){

return agentID;

}

}

 

package witharraylist;

//새로운 고객 등급 추가하기

 

public class GoldCustomer extends Customer{

double saleRatio;

 

public GoldCustomer(int customerID, String customerName) {

super(customerID, customerName);

customerGrade = "GOLD";

bonusRatio = 0.02;

saleRatio = 0.1;

}

 

public int calcPrice(int price) {

bonusPoint += price * bonusRatio;

return price - (int)(price * saleRatio);

}

}

 

package witharraylist;

 

import java.util.ArrayList;

 

//배열을 활용한 고객 관리 프로그램 구현

public class CustomerTest {

 

public static void main(String[] args) {

ArrayList<Customer> customerList = new ArrayList<Customer>();

 

Customer c1 = new GoldCustomer(101,"이성계");

Customer c2 = new Customer(102,"이방과");

Customer c3 = new GoldCustomer(103,"이방원");

Customer c4 = new VIPCustomer(104,"이도",10);

Customer c5 = new Customer(105,"이향");

 

customerList.add(c1);

customerList.add(c2);

customerList.add(c3);

customerList.add(c4);

customerList.add(c5);

 

System.out.println("고객정보출력");

for(Customer customer : customerList) {

System.out.println(customer.showCustomerInfo());

}

 

System.out.println("할인율과 보너스 포인트 계산");

int price = 10000;

for(Customer customer : customerList) {

int cost = customer.calcPrice(price);

System.out.println(customer.getCustomerName() + "이/가 " + cost + " 지불");

System.out.println(customer.getCustomerName() + "의 현재 보너스 포인트는 " + customer.bonusPoint +"점");

}

}

}

그림 4. 다형성과 배열 활용

 

다운 캐스팅 instanceof

하위 클래스로 형 변환, 다운 캐스팅

상위 클래스로 형 변환되었던 하위 클래스를 다시 원래 자료형으로 형 변환하는 것을 다운 캐스팅(down casting)이라고 함

 

instanceof

다운 캐스팅을 하기 전에 상위 클래스로 형 변환된 인스턴스의 원래 자료형을 확인해야 변환할 때 오류를 막을 수 있음.

이를 확인하는 예약어가 instanceof

 

728x90

'KDT > Java' 카테고리의 다른 글

231220 Java  (0) 2023.12.20
231218 Java  (0) 2023.12.18
231213 Java  (0) 2023.12.13
231211 Java  (0) 2023.12.11
231207 Java  (0) 2023.12.07