最近发现,有时候new一个对象,赋值给变量,变量前面不需要写对象类型。
但是有时候new一个对象并且赋值给变量,就必须说明该变量的对象类型。
到底是什么原理呢?
我们直接看代码。
首先给出一个Animal类
package CatAndDog;
public class Animal {
private int age = 80;
private String name = "动物";
public Animal() {
}
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat(){
System.out.println("动物吃东西");
}
public void sleep(){
System.out.println("动物要睡觉");
}
}
然后给出一个Cat类,继承自Animal类。
package CatAndDog;
public class Cat extends Animal {
public Cat() {
}
public Cat(int age, String name) {
super(age, name);
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
最后,重点在测试类
package CatAndDog;
public class Demo {
public static void main(String[] args) {
Animal a = new Cat();
a.setAge(20);
a.setName("加菲");
System.out.println(a.getName()+","+a.getAge());
a.eat();
System.out.println(a.getClass());
Cat c =new Cat();
System.out.println(c.getAge());
a=new Cat(); //这里没有报错
System.out.println(a.getClass());
a=new Animal(); //这里也没有报错
System.out.println(a.getClass());
c2=new Cat(20,"加菲"); //这里报错
}
}
第一次创建对象时,Animal a = new Cat();这是一个多态的使用,由父类引用指向子类对象,显然不会有问题。这里可以输出a.getClass(),发现a的对象类型是Cat。
第二次创建对象时,Cat c =new Cat();创建了一个猫类的对象,也不会有任何问题。
第三次创建对象时,a=new Cat(); 这里也不会报错,因为刚才已经给a分配了内存,new了一个Cat类赋值给a,a的地址发生改变,指向了一个新的Cat类。
第三次创建对象时,a=new Animal(); 这里也不会报错,和上一条一样,a的地址发生改变,指向了一个新的Animal类。
第五次创建对象时,c2=new Cat(20,"加菲"); 由于前面没有给创建变量c2,所以不能直接给它分配内存。
所以,第一次声明一个引用类型变量时,必须声明它的类名,第二次给这个变量赋值时,可以声明它的类型了。
其实这里和基本类型的变量的声明规则类似,比如int,初始化的时候必须声明类型,第二次就相当于赋值了,可以不声明类型。二者的区别是,引用类型变量的变量传递的是一个地址值,因此,在给a第二次赋值时,既可以指向一个Cat类,又可以指向一个Animal类,传递的都是地址,赋值的也是地址;在给int类型的变量第二次赋值时,赋值的是内容,只能赋值一个int数值,而不能把float类型的数值赋值给它。