构造方法java - 在Java中调用哪个重载方法



java调用构造方法 (4)

特定问题解决方案

在某些语言中,参数被解析为其动态类型,但不是在java中。 编译器已经在编译时确定了你的 getWorkDetail(this); 会去。 thisPerson 类型,因此 getWorkDetail(Person e) 。 在您的具体情况下,解决方案非常明显。 正如其他人已经指出的那样,您需要覆盖 Employee 类中的 getWorkDetail()

解析其动态参数类型的方法

要解决在运行时解析参数类型的一般问题,应避免使用 instanceof 运算符,因为它通常会导致不干净的代码。

如果您有两个不同的类,则无法再实现上述简单的解决方案。 在这些情况下,您将不得不使用 访问者模式

考虑以下类:

public interface Animal {
    default void eat(Food food) {
        food.eatenBy(this);
    }

    void eatMeat(Meat meat);

    void eatVegetables(Vegetables vegetables);
}

public class Shark implements Animal {
    public void eatMeat (Meat food) {
        System.out.println("Tasty meat!");
    }

    public void eatVegetables (Vegetables food) {
        System.out.println("Yuck!");
    }
}

public interface Food {
    void eatenBy(Animal animal);
}

public class Meat implements Food {
    public void eatenBy(Animal animal) {
        animal.eatMeat(this);
    }
}

public class Vegetables implements Food {
    public void eatenBy(Animal animal) {
        animal.eatVegetables(this);
    }
}

你可以这样打电话:

Animal animal = new Shark();
Food someMeat = new Meat();
Food someVegetables= new Vegetables();
animal.eat(someMeat);        // prints "Tasty meat!"
animal.eat(someVegetables);  // prints "Yuck!"

在调用 Animal.eat 访问者模式 之后,将调用 Food.eatenBy ,它由 MeatVegetables 。 这些类将调用更具体的 eatMeateatVegetables 方法,它使用正确的(动态)类型。

我有一个基本的继承情况与超类中的重载方法。

public class Person {
    private String name;
    private int dob;
    private String gender;

    public Person(String theName, int birth, String sex){
        name = theName;
        dob = birth;
        gender = sex;
    }

    public void work(){
        getWorkDetail(this);
    }

    public void getWorkDetail(Employee e){
        System.out.println("This person is an Employee");
    }

    public void getWorkDetail(Person p){
        System.out.println("This person is not an Employee");
    }
}

以下 Employee 类扩展了上面的 Person 类:

public class Employee extends Person {

    String department;
    double salary;

    public Employee(String theName, int birth, String sex){
        super(theName, birth, sex);
        department = "Not assigned";
        salary = 30000;
    }
}

main方法只是创建一个 Employee 对象(静态和动态类型)并在其上调用 .work()

public static void main(String[] args){
    Employee e1 = new Employee("Manager1", 1976, "Female");
    e1.work();
}

这最终打印

This person is not an Employee

通过这个看,我原以为由于对象 e1 的静态和动态类型都是 Employee 它会调用Person中的重载方法,它将 Employee 作为参数。 因为我对此明显错误,所以我打开了一个调试器,假设在 Person 类中的 getWorkDetail(this) 行中的“this”引用必须已经变形为它的超类。 然而,这不是我发现的。

显然,在代码中 this 是一个 Employee 对象,但它仍然选择执行重载方法 getWorkDetail(Person p) 。 谁能解释这种行为?


Answer #1

getWorkDetail(this)不知道子类是什么。 改为调用getWorkDetail。


Answer #2

重载解析在编译期间发生,而不是在运行时。

因此,当您调用 getWorkDetails(this) ,假定 this 是一个 Person (它是静态类型),因此称为相应的重载。

注意:在 Employee 类中使用它会使它成为 Employee 类型。 您可以通过在 Employee 重载 work() 来验证这一点。

class Employee extends Person {
    ...

    public void work() {
        getWorkDetails(this); // This should print "This person is an Employee"
    }
}

Answer #3

通话偏好

class Foo {
    static void test(int arg) { System.out.println("int"); }
    static void test(float arg) { System.out.println("float"); }
    static void test(Integer arg) { System.out.println("Integer"); }
    static void test(int... arg) { System.out.println("int..."); }

    public static void main(String[] arg) {
        test(6);
    }
}

输出将在控制台上打印。 现在你评论第一个 test() 方法,看看输出的是什么。

这是原始数据类型中的首选hirarchey。 现在来到派生类型 FooChild 像这样声明一个类 FooChild

class FooChild extends Foo {

}

并在 Foo 创建两个新方法

static void testChild(Foo foo) { System.out.println("Foo"); }
static void testChild(FooChild fooChild) { System.out.println("FooChild"); }

然后在main方法中尝试调用 testChild 就像这个 testChild(new FooChild());





overloading