java 다형성2

조항주·2022년 5월 8일

study

목록 보기
8/20
post-thumbnail

참조변수와 인스턴스의 연결

조상 클래스에 선언된 멤버변수와 같은 이름의 인스턴스 변수를 자손 클래스에 중복으로 정의했을 때, 조상타입의 참조변수로 자손 인스턴스를 참조하는 경우와 자손타입의 참조변수로 자손 인스턴스를 참조하는 경우에는 서로 다른 결과를 얻는다.

public class Main {
    static class Parent {
        int x = 100;

        void method() {
            System.out.println("Parent Method");
        }
    }
    static class Child extends Parent {
        int x = 200;

        void method() {
            System.out.println("Child Method");
        }
    }
    public static void main(String[] args) {
        Parent p = new Child();
        Child c = new Child();

        System.out.println("p.x = "+p.x);
        p.method();
        System.out.println("c.x = "+c.x);
        c.method();
    }
}

super 키워드를 사용하면 어떻게 출력될까

public class Main {
    static class Parent {
        int x = 100;

        void method() {
            System.out.println("Parent Method");
        }
    }
    static class Child extends Parent {
        int x = 200;

        void method() {
            System.out.println("Child Method");
            System.out.println("super.x="+super.x);
            System.out.println("super.x="+this.x);
        }
    }
    public static void main(String[] args) {
        Parent p = new Child();
        Child c = new Child();

        System.out.println("p.x = "+p.x);
        p.method();
        System.out.println("c.x = "+c.x);
        c.method();
    }
}

매개변수의 다형성

메서드의 매개변수에도 다형적인 특징이 적용된다

class Product {
    int price; // 제품 가격

    Product(int price){ // 생성자
    this.price = price;
    }
}

class Tv extends Product {
    Tv() {
        //조상 클래스의 생성자 Product(int price)를 호출.
        super(100); // Tv의 가격을 100만원으로 한다.
    }
    @Override
    public String toString() {
        //Object 클래스의 toString()을 오버라이딩한다.
        return "TV";
    }
}

class Computer extends Product {
    Computer() {
        super(200);
    }
    @Override
    public String toString() {
        return "Computer";
    }
}

class Buyer { // 고객
    int money = 1000; // 소유금액
    void buy(Product p) {
    // 매개 변수가 Product 타입의 참조변수. Product 클래스의 자손 클래스 Tv, Computer의 참조변수를 한번에 매개변수로 받아들일 수 있음.
    // 앞으로 다른 제품 클래스를 추가할 때 Product클래스를 상속받기만 하면, buy(Product  p)메서드의 매개변수로 받아들여질 수 있다.
    if(money<p.price) {
        System.out.println("잔액이 부족하여 물건을 살수 없습니다.");
        return;
    }
    money -= p.price; // 가진 돈에서 구입한 제품의 가격을 뺀다.
    }
}
public class PolyArgumentTest {
    public static void main(String[] args) {
        Buyer b = new Buyer();
        Tv tv = new Tv();
        Computer com = new Computer();

        b.buy(tv); // tv 구매
        b.buy(com); // computer 구매
    }
}

여러 종류의 객체를 배열로 다루기

조상타입의 참조변수로 자손타입의 객체를 참조하는 것이 가능하므로 Product클래스가 TV, Computer, Audio클래스의 조상일 때, 다음과 같이 할 수 있다

Product p1 = new Tv();
Product p2 = new Computer();
Product p3 = new Audio();

Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio;

Vector ArrayList

ArrayList는 기존의 Vector를 개선한 것으로 Vector와 구현원리와 기능적인 측면에서 동일하다고 할 수 있다. Vector는 기존에 작성된 소스와의 호환성을 위해서 계속 남겨두고 있을 뿐이기 때문에 가능하면 Vector보다는 ArrayList를 사용하자

둘의 차이점

  1. 동기화: ArrayList는 동기화가 되어있지 않지만 Vector는 동기화가 되어있다
    이 말의 뜻은 ArrayList는 멀티 스레드(Multi-Thread)에서 작업이 가능하지만 Vector는 단일 스레드에서만 사용이 가능합니다

  2. 배열의 길이 증가: 배열의 최대 길이까지 왔을 때 ArrayList는 크기가 지정되어 있지 않을 때 50%씩 증가합니다. 하지만 Vector는 2배씩 크기가 증가한다는 점을 가지고 있습니다

  3. 동기, 비동기: ArrayList는 비동기이어서 많은 스레드가 동시에 작동할 수 있으므로 한 번에 하나의 스레드 만 작동할 수 있는 Vector보다 좋은 성능을 가지고 있습니다

  4. 스레드 안전: 멀티 스레드 프로그래밍에서 여러 스레드가 동시에 접근했을 때 프로그램 실행에 있어서 문제가 나지 않음을 뜻합니다. ArrayList는 동기화되어 있지 않아 동기화할 필요가 없고 Vector는 동기화되어있기 때문에 한 번에 하나의 스레드만 접근이 가능하여 안전합니다

import java.util.ArrayList;
import java.util.Vector;

public class Main {
    
    public static void main(String[] args) {
        Vector<Integer> vector = new Vector<>(7);
        ArrayList<Integer> arrayList = new ArrayList<>(7);

        for (int i = 0; i < 10; i++) {
            vector.add(i);
            arrayList.add(i);
        }

        for (int i = 0; i < 10; i++) {
            System.out.println("vector.get(i) = " + vector.get(i) + " arrayList.get(i) = " + arrayList.get(i));
        }
        System.out.println("vector.capacity() = " + vector.capacity());
    }
}

0개의 댓글