Как вызвать другой метод с заданным классом аргумента в Java - PullRequest
0 голосов
/ 20 декабря 2018

Допустим, у нас есть следующий код:

class Parent {}

class Child1 extends Parent {}

class Child2 extends Parent {}

class Main {
    static void method(Parent obj) {}
    static void method(Child1 obj) {}
    static void method(Child2 obj) {}
    public static void main(String[] arg) {
        Parent obj1 = new Child1();
        Parent obj2 = new Child2();
        method(obj1); //call method(Child1 obj)
        method(obj2); //call method(Child2 obj)
    }
}

Как получить подобный эффект, чтобы объект можно было доставить в конкретный метод вместо общего?

------------------------ Пример серверальных параметров --------------

class Parent {}

class Child1 extends Parent {}

class Child2 extends Parent {}

class Main {
    static void method(Parent obj1, Parent obj2) {}

    static void method(Child1 obj1, Child1 obj2) {}

    static void method(Child1 obj1, Child2 obj2) {}

    public static void main(String[] arg) {
        Parent obj1 = new Child1();
        Parent obj2 = new Child2();
        method(obj1, obj1); //call method(Child1 obj1, Child1 obj2)
        method(obj1, obj2); //call method(Child1 obj1, Child2 obj2)
    }
}

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Я нашел решение, подобное этому:

class Parent {}

class Child1 extends Parent {}

class Child2 extends Parent {}

public class Main {
    static void method(Parent obj) {
        System.out.println("Parent");
        if(obj instanceof Child1)
        {
            method((Child1) obj);
            return;
        } else if(obj instanceof Child2)
        {
            method((Child2) obj);
            return;
        }
    }
    static void method(Child1 obj) {
        System.out.println("Child1");
    }
    static void method(Child2 obj) {
        System.out.println("Child2");
    }
    public static void main(String[] arg) {
        Parent obj1 = new Child1();
        Parent obj2 = new Child2();
        method(obj1); //call method(Child1 obj)
    }
}

Для этого кода вывод:

Parent
Child1

Так что это означает, что когда мы помещаем объект типа Child1, тогда метод для Parentбудет вызван, а затем он проверит внутри этого метода, если объект имеет тип Child1, если да, тогда вызовите метод для Child1.

Пока объект, переданный в качестве аргумента этому методу, не является типом Parent, нет способа вызватьChild1 или Child2

0 голосов
/ 10 июля 2019

Предыстория: я сталкиваюсь с почти такой же проблемой при написании проекта компилятора

Короткий ответ : Если вы придерживаетесь того, чтобы код расширялся , а также был легко написан (как примеры кода в вопросе), вероятно, вам придетсядобавьте к нему отражения (хотя это может быть неприемлемо для статических анализаторов).

Пример:

import java.lang.reflect.*;
import java.util.*;

class Value {}

class IntValue extends Value {
    private int value;
    public int value() {
        return value;
    }
    public IntValue(int value) {
        this.value = value;
    }
    public String toString() {
        return String.valueOf(value);
    }
}

class StringValue extends Value {
    private String value;
    public String value() {
        return value;
    }
    public StringValue(String value) {
        this.value = value;
    }
    public String toString() {
        return value;
    }
}

class Operator {
    public Value apply(Value x, Value y) throws ArithmeticException {
        try {
            var method = this.getClass().getDeclaredMethod("apply", x.getClass(), y.getClass());
            return (Value) method.invoke(this, x, y);
        } catch (InvocationTargetException exception) {
            throw (ArithmeticException) exception.getCause();
        } catch (Exception ignore) {
            return null;
        }
    }

    private IntValue apply(IntValue x, IntValue y) {
        return new IntValue(x.value() / y.value());
    }

    private StringValue apply(StringValue x, StringValue y) {
        return new StringValue(x.value() + y.value());
    }
}

public class Main {
    public static void main(String[] args) {
        var op = new Operator();

        System.out.println(op.apply(new IntValue(6), new IntValue(2)));
        System.out.println(op.apply(new StringValue("a_str"), new StringValue("b_str")));

        try {
            System.out.println(op.apply(new IntValue(6), new IntValue(0)));
        } catch (ArithmeticException exception) {
            exception.printStackTrace();
        }
    }
}

Дайте мне знать, если у вас есть лучшие решения.

0 голосов
/ 20 декабря 2018

Что вы спрашиваете об этом методе перегрузки.Перегрузка метода разрешается во время компиляции и поэтому использует тип времени компиляции соответствующих переменных, чтобы определить, какой метод выполнить.

Следовательно method(obj1) и method(obj2) всегда будут вызывать static void method(Parent obj), так кактип времени компиляции obj1 и obj2 равен Parent.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...