Java - вызов метода путем передачи дочернего экземпляра функции с параметром типа родительского класса [duplicate]

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
5
задан Learner 6 May 2014 в 11:34
поделиться

5 ответов

Подход, который я, наконец, принимаю, - это определить интерфейс, скажем FooInterface с foo() методом, и пусть все дочерние классы реализуют его, тогда я мог бы просто набрать cast obj для этого интерфейса и вызвать метод foo() например:

Parent obj = ...// Object of one of the child classes
.....
if(obj instanceof FooInterface){
    ((FooInterface)obj).foo();
}
1
ответ дан Learner 18 August 2018 в 19:48
поделиться

Если вы хотите использовать только тип, тогда нет необходимости добавлять интерфейс. Вы можете привести его в желаемый класс и вызвать метод. Пример

public class HelloWorld {
    public static void main(String args[]) throws FileNotFoundException {
        SuperClass sc =new Child1();
        if(sc instanceof Child1)//Do same for Child2
        ((Child1)sc).foo();
    }
}

class SuperClass {

}

class Child1 extends SuperClass{
    public void foo(){
        System.out.println("From child1");
    }
}

class Child2 extends SuperClass{
    public void foo(){
        System.out.println("From child2");
    }
}

Выход: из child1

0
ответ дан Aniket Thakur 18 August 2018 в 19:48
поделиться
  • 1
    Ну, вот что я считаю не хорошим подходом и поэтому не хочу его использовать. Если есть несколько дочерних классов, это было бы уродливо. Не так ли? – Learner 6 May 2014 в 10:10

Вы не можете сделать это с помощью ссылки на родительский объект до тех пор, пока не будет объявлен метод except в самом родительском классе / интерфейсе.

Вы должны сбрасывать его на дочерний класс, поскольку родительский класс / интерфейс не имеет любое знание о дочернем классе, отличном от контракта, определенного между ними.

Здесь contract означает abstract methods.


вы можете попробовать таким образом, нужно проверить его.

FooInterface sc =new Child1();
sc.foo();

...

interface FooInterface{
    void foo();
}

public class Parent {

}

public class Child1 extends Parent implements FooInterface{

    public void foo() {

    }
}

public class Child2 extends Parent implements FooInterface{

    public void foo() {

    }
}
0
ответ дан Braj 18 August 2018 в 19:48
поделиться
  • 1
    С помощью этого решения я не смогу вызывать методы на sc, которые существуют в классе родителя. Я отредактировал свой вопрос, чтобы упомянуть об этом. Благодарю. – Learner 6 May 2014 в 12:35
  • 2
    Вы сделали Child1 орудий FooInterface одинаковыми для Child2? – Braj 6 May 2014 в 12:49
  • 3
    Это то, что я упомянул в «Моем решении», только разница в том, что в моем решении ссылка имеет тип Parent, и поэтому мне нужно использовать instanceof один раз, чтобы узнать, имеет ли он тип FooInterface. – Learner 6 May 2014 в 13:56
  • 4
    поэтому вы не хотите менять свой дизайн, тогда это невозможно, поскольку я сказал вам, что родительский класс / интерфейс не имеет каких-либо знаний о дочернем классе. как родительский класс / интерфейс знает, что ребенок имеет создал x методы? – Braj 6 May 2014 в 14:00
  • 5
    Как насчет моего решения, которое я упомянул в вопросе? он действительно решает мою проблему. Но хороший подход - это то, что я хочу знать? – Learner 6 May 2014 в 15:32

Вы можете реализовать AbstractChild, наследующий от Parent, а затем расширить этот класс вместо Parent:

public class Parent {
    ....
}

public abstract class AbstractChild extends Parent{

    public abstract void foo();

}



public class Child1 extends AbstractChild {
    ....
    public void foo() {
        ....
    }
}

public class Child2 extends AbstractChild {
    ....
    public void foo() {
        ....
    }
}

. Поэтому вам нужно только проверить, является ли ваш экземпляр instanceof AbstractChild.

0
ответ дан davioooh 18 August 2018 в 19:48
поделиться

Полиморфизм применяется к объектной ссылке, а не к типу. Когда вы вызываете

FooInterface obj = ...// Object of one of the child classes
obj.foo(); 

, вызывается метод дочернего класса foo().

1
ответ дан Roman C 18 August 2018 в 19:48
поделиться
  • 1
    Посмотрите на вопрос ОП еще раз. Parent не имеет никакого метода foo(). – Braj 6 May 2014 в 10:05
  • 2
    @braj Почему нет? – Roman C 6 May 2014 в 10:09
  • 3
    Как вы можете вызвать метод по ссылке интерфейса, где интерфейс не объявил этот метод? Посмотри на мой пост. – Braj 6 May 2014 в 10:10
  • 4
    @Learner Еще один комментарий к вам, когда вы разрабатываете свои классы, рассматривайте кодирование для интерфейсов, а не для классов. – Roman C 6 May 2014 в 10:20
  • 5
    @RomanC, с этим решением я не смогу вызывать методы на obj, которые существуют в классе Parent. Да, я понимаю преимущество кода для интерфейса, но это устаревший код, и я НЕ МОЖЕТ изменить класс Parent. – Learner 6 May 2014 в 10:21
Другие вопросы по тегам:

Похожие вопросы: