Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
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 ");
}
}
}
Подход, который я, наконец, принимаю, - это определить интерфейс, скажем FooInterface
с foo()
методом, и пусть все дочерние классы реализуют его, тогда я мог бы просто набрать cast obj для этого интерфейса и вызвать метод foo()
например:
Parent obj = ...// Object of one of the child classes
.....
if(obj instanceof FooInterface){
((FooInterface)obj).foo();
}
Если вы хотите использовать только тип, тогда нет необходимости добавлять интерфейс. Вы можете привести его в желаемый класс и вызвать метод. Пример
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
Вы не можете сделать это с помощью ссылки на родительский объект до тех пор, пока не будет объявлен метод 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() {
}
}
sc
, которые существуют в классе родителя. Я отредактировал свой вопрос, чтобы упомянуть об этом. Благодарю.
– Learner
6 May 2014 в 12:35
Parent
, и поэтому мне нужно использовать instanceof
один раз, чтобы узнать, имеет ли он тип FooInterface
.
– Learner
6 May 2014 в 13:56
Вы можете реализовать 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
.
Полиморфизм применяется к объектной ссылке, а не к типу. Когда вы вызываете
FooInterface obj = ...// Object of one of the child classes
obj.foo();
, вызывается метод дочернего класса foo()
.
obj
, которые существуют в классе Parent
. Да, я понимаю преимущество кода для интерфейса, но это устаревший код, и я НЕ МОЖЕТ изменить класс Parent
.
– Learner
6 May 2014 в 10:21