引导
首先我们首先新建三个类——Mammal(哺乳类),Whale(鲸鱼类),Earth(地球类)。
public class Mammal{
public void move(){
System.out.println("奔跑");
}
}
public class Whale extends Mammal{
@Override
public void move(){
System.out.println("用鳍游动");
}
}
public class Earth {
public static void main(String[] args) {
Whale whale = new Whale();
whale.move();////当子类对象调用重写后的方法时,调用的是子类重写后的方法
}
}
对于Earth类中的whale对象而言,当子类对象调用重写之后的方法时,调用的是子类重写之后的方法,显而易见,但这不是多态。
继续对Earth类而言——
public class Earth {
public static void main(String[] args) {
Whale whale = new Whale();
whale.move();////当子类对象调用重写后的方法时,调用的是子类重写后的方法
double price = 9;
Mammal mammal = new Whale();//自动类型转换:父类类型的变量指向其子类创建的对象 对象上转型 new Whale()上转型对象
mammal.move();
}
}
首先让我们来看double price=9;这行代码,我们知道double是双精度浮点型,9是整形值,毫无疑问小于double的范围,这个时候系统自动的把9的范围上调,变成double类型的值。
因为mammal变量类型是Mammal类,所以表面上调用的是Mammal类中的方法;但因为mammal变量保存了new Whale()地址,
所以再程序运行时JVM根据地址找到new Whale(),实质是new Whale().move(),即运行时调用的是子类重写的方法 即多态。
思考
在多态前提下,父类中那些被子类重写的方法的方法体没有实质的作用,是否还需要?
显而易见,如果只对子类重写的方法有需求的话,父类中原本的方法是什么样无关紧要,可以舍弃。
抽象方法与抽象类
抽象方法:没有方法体的方法,例如:
public abstract void eat();
一个类中如果有一个抽象方法,则该类必须为抽象类
public abstract class Father {
public void move(){
System.out.println("移动");
}
public abstract void eat();
}
抽象类中的抽象方法是多态的一种表现形式。
抽象类的特点
1、抽象类有构造方法,但是不能创建对象
对于抽象类我们可以在里面自己定义一个构造方法,不会报错,这说明抽象类允许其中存在构造方法——那么可推出抽象类本身就有系统默认的构造方法。
抽象类不能创建对象,试想,一旦可以创建对象,那么必然可以对象名.方法名引用,但是万一引用的是一个抽象方法——里面什么也没有,就会出错,于是Java语言规定抽象类不能创建对象。
2、如果一个类没有重写完父类中的所有抽象方法,则该类必须为抽象类
3、抽象类中可以没有抽象方法
抽象类中可以没有abstract方法(为了强迫使用者必须通过继承来使用这个类);但是一旦类中包含了abstract方法,则这个“类”一定是abstract类,即有抽象方法的类一定是抽象类。
4、抽象类与普通类:
a、抽象类有abstract 修饰 普通类没有
b、抽象类不能创建对象,普通类可以创建对象
c、抽象类中可以有抽象方法,普通类绝对不能有抽象方法
注意:一个含有抽象方法的抽象类必须至少要有一个非抽象类的子类!
发散思考
•abstract final class Mammal{ } 能否编译通过,?为什么?
不能!
原因:如果抽象类前面可以添加final就意味着该类无法被继承,也就意味着该抽象类中的抽象方法永远无法得到实现,也就意味着抽象类中的抽象方法是无用的。
•Mammal抽象类中move抽象方法的访问权限可以为private吗,即“private abstract void move();”, 为什么?
不能!
原因:被private修饰的方法其作用范围为本类,如果抽象类中的抽象方法被private修饰就意味着该方法永远无法被实现。
•Mammal抽象类中move抽象方法可以由static修饰吗,,即“public static abstract void move();” 为什么?
不能!
原因:抽象类中的抽象方法如果可以被static修饰就意味着可以使用抽象类的类名来使用该方法,但是该抽象方法没有方法体,不具有使用的价值,所以Java中规定抽象类中不能包含被static修饰的静态抽象方法。