JAVA多态
1.概念
在《Java核心技术 卷一》中是这样描述的:一个对象变量可以指示多种实际类型的现象被称为多态。
这样一句话感觉很难理解,下面我们用代码进行表述,
2.代码示例
首先,创建一个动物类,代码如下:
public class Animal {
//动物的年龄
private int age;
//动物的性别
private String gender;
//睡觉方法
public void sleep() {
System.out.println("动物在睡觉");
}
//静态方法
public static void show() {
System.out.println("这是动物的静态方法");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
在根据这个动物类创建一个狗的子类:
public class Dog extends Animal{
//狗的名字
private String name;
//重写父类的方法
@Override
public void sleep() {
System.out.println(name+"在睡觉");
}
//静态方法
public static void show() {
System.out.println("这是狗的静态方法");
}
//子类自己的方法
public void name() {
System.out.println("狗的明细");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在测试类中,我们可以做这样的实验:
实验一:
1.首先定义一个动物的对象变量
2.分别引用狗对象
3.调用静态的show方法和被重写的sleep方法
Animal animal;
animal = new Dog();
animal.show();
animal.sleep();
Class class1 = animal.getClass();
结果如图所示:
可以看出他调用了父类的静态方法和dog类中重写了的sleep方法。
这是为何呢,我们接着往下看。
实验二:
在子类中重写父类的静态方法:
我们发现出错了,错误提示我们不能添加@Override这个注解,换言之,该方法不能被重写。
实验三:
去掉Dog类中的show方法,创建main方法,直接调用show方法:
结果如下图所示:
调用了父类的静态方法,也就是说父类的方法是可以被继承下来的。
综合前三个实验,我们发现,静态方法是可以被继承的,但是却不能被重写(覆盖),在实验一中我们吃惊的发现,这样说在dog类中存在两个一样的方法(只有方法体不一样),但是却没有报错。
这是因为静态方法属于类,在编译阶段类被加载时,类的静态方法或者属性就会被分配内存,存储到类所在的内存中。也就是说虽然有两个一样的方法,但是这两个方法使属于两个类的,可以做到互不干扰。
一个父类的变量,指向子类的对象,调用一个子类也有的静态方法时,由于这是一个父类的变量,并且静态方法属于类,所以在调用时,JVM会去父类所在的内存中寻找这个方法,所以最终的结果就是调用父类的方法,而不是子类的方法。
3.结论
总结来说多态就是父类的对象变量可以引用子类的对象。但反过来就不可以,可以根据例子这样理解:狗(子类)属于动物(父类),但动物(父类)不一定是狗(子类)。但是无论引用了哪个子类,在编译器中依然会认为这是一个父类变量,因此父类虽然引用了子类的对象,但是不能调用子类自己的方法和变量。
在静态方法这个方面,子类不能重写父类的静态方法。在多态中会直接调用父类的静态方法。