[Java] instanceof and others...

조현호_ChoHyeonHo·2025년 1월 10일
public class InstanceOfTest {
    public static void main(String[] args) {
        FireEngine fe = new FireEngine();
        if(fe instanceof FireEngine){
            System.out.println("fe instanceof FireEngine");
        }
        if (fe instanceof Car) {
            System.out.println("fe instanceof Car");
        }
        if (fe instanceof Object) {
            System.out.println("fe instanceof Object");
        }

    }
}

class Car{}
class FireEngine extends Car{}

어떤 타입에 대한 isntance of 연산의 결과가 true라는 것은 검사한 타입으로 형변환이 가능하다는 뜻이다. upcasting이 가능하다는 뜻이기 때문이다. downcasting은 자동이고

Connecting Refernce variable and instance

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

이것을 풀어서 생각하면,,,
우선 참조 변수가 참조하는 인스턴스가 참조변수 타입의 자손일 경우, 인스턴스에 더 많은 멤버가 있음에도 그것이 참조변수의 타입에 포함되지 않으면 '숨겨짐' 되기 때문에 사용할 수 없다.

하지만, 멤버가 조상과 자식에 중복정의 됐을 경우 참조변수가 조상 타입이면 조상의 멤버, 자식이면 자식의 멤버를 참조하게 된다.
그러나 이것은 변수에 국한되고, 메서드는 인스턴스의 메서드가 바로 호출된다. 왜? 메서드는 오버라이딩 되기 때문이다.

Variables are hided, no matter they are primiteve type or referencial type.
Methods are overrided.

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


class Parent{
    int x = 100;    
    String s = "parent!";
    String method(){
        return "parent method";
    }
}
class Child extends Parent{
    int x = 400;    
    String s = "child!";
    String method(){
        return "child method";
    }
}

this results

100
child method
parent!
400
child method
child!

If you remove all the members in child, then instance c will output every member of parent, includig method which is not overrided or has done anything.

Then suppose we have identical members in both parent and child. if we have Parent type instance p and Child type instance c, how can we discreminate members?

public class BindingTest2{
    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();
        System.out.println("c.x=" + c.x);
        c.method();
    }
}

class Parent{
    int x = 100;
    void method(){
        System.out.println("Parent Method");
    }
}

class Child extends Parent{
    int x = 200;

    void method(){
        System.out.println("x=" + x);
        System.out.println("super.x=" + super.x);
        System.out.println("this.x=" + this.x);
    }
}

results...

p.x=100 // referenced parent type.(child's x has been hided.)
x=200 // this is called from overrided method, having identical meaning `this.x` 
super.x=100 // this works identically whether the instance has referenced by parent or child. 
this.x=200

c.x=200
x=200
super.x=100
this.x=200

Polymorphism via Argument(referencial)

Q. 그러니까, 다형성을 구현하되, 매개변수를 참조형 변수들의 어떤 조상으로 정의해서 어떤 자손들이 매개변수에 들어가느냐에 따라 동작이 달라지게 하는 거지?
A. 네, 정확히 이해하셨습니다! 말씀하신 대로, 매개변수의 다형성은 메서드의 매개변수를 조상 클래스(참조형 변수 타입)로 정의하고, 실제로 전달되는 자손 클래스 객체에 따라 동작이 달라지는 방식으로 구현됩니다.

class Product
{
    int price; 
    int bonusPoint;

    public Product(int price) {
        this.price = price;
        bonusPoint = (int)(price/10.0);
    }
}

class Tv extends Product{
    Tv(){
        super(100);
    }

    public String toString(){
        return "Tv";
    }
}

class Computer extends Product{

    public Computer() {
        super(200);
    }

    public String toString(){
        return "Computer";
    }
}

class Buyer{
    int money = 1000;
    int bonusPoint = 0;

    void buy(Product p){
        if(money < p.price){
            System.out.println("Not enough balance.");
            return;
        }

        money -= p.price;
        bonusPoint += p.bonusPoint;
        System.out.println("You have purchased " + p);
    }
}


public class PolyArgumentTest {
    public static void main(String[] args) {
        Buyer b = new Buyer();
        Tv t = new Tv();
        Computer com = new Computer();

        b.buy(t);
        b.buy(com);
        System.out.println("Balance: " + b.money);
        System.out.println("Bonus Point: " + b.bonusPoint);
    }
}
profile
Behold the rabbit hole

0개의 댓글