父类名 a = new 子类名()
子类名 b = new 子类名()
比较上面两种创建实例的区别:
a只能调用父类的函数,和子类重写父类的方法,不能调用父类中不存在的子类的函数,因为它没有继承。a是父类的引用,指向了一个子类对象,好处如果一旦发现该B对象无法适应 当前环境,可以转换成父类中的其它对象。
b可以调用父类的函数也可以调用子类的函数。
这里我们定义一个子类和一个父类
//父类
public class Animal {
String name;
int age;
public Animal(String name){
this.name=name;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void getage(){
System.out.println(name+"年龄是"+age);
}
}
//子类
public class Dog extends Animal{
String name;
int age;
public Dog(String name) {
super(name);
// this.name=name;
}
public void eat(){
System.out.println(name+"正在吃ff");
}
public void neweat(){
System.out.println("neweat");
}
}
我们创建a和b两个实例 :
public class Manage {
public static void main(String args[]){
Animal a = new Dog("a");
Dog b = (Dog) new Animal("b");
a.eat();
a.neweat();
a.getage();
b.eat();
b.neweat();
b.getage();
}
}
由于a是父类animal类的引用并指向子类,a无法调用子类dog的neweat方法,程序a.getage();会报错。实际上a被向上转型为animal类,即父类。
在java中,子类不能被强制转型成父类,所以Dog b = (Dog) new Animal("b");这行命令会报错。
在删除这两条指令后:
public class Manage {
public static void main(String args[]){
Animal a = new Dog("a");
a.eat();
a.getage();
}
}
程序可以顺利运行,只不过在子类和父类中都有的eat方法执行时调用的是子类重写的eat方法
输出结果为:
null正在吃ff
a年龄是0
由于子类中只继承了父类的构造方法,在创建a实例时先创建了父类的实例,调用父类的构造方法,将属性name赋值给了父类实例,子类实例的name默认是null,所以子类重写方法被调用时输出的name是null,父类的方法输出的name是"a".