先复习一下上节内容——重写、多态
1、重写
Whale whale = new Whale();
whale.move();//调用的是子类重写后的方法
2、多态
public static void main(String[] args) {
// double price = 9;
Mammal mammal = new Whale();
mammal.move();
/*因为mammal变量类型是Mammal类,所以表面上调用的是Mammal类中的方法;但因为mammal变量保存了new Whale()地址,
*所以再程序运行时JVM根据地址找到new Whale(),实质是new Whale().move(),即运行时调用的是子类重写的方法 即多态
*/
因为Mammal 是父类,可以类比自动类型转换,创一个new Whale()对象。
因为mammal变量类型是Mammal类,所以表面上调用的是Mammal类中的方法;但因为mammal变量保存了new Whale()地址,
所以再程序运行时JVM根据地址找到new Whale(),实质是new Whale().move(),即运行时调用的是子类重写的方法 即多态
思考:在多态前提下,父类中那些被子类重写的方法的方法体没有实质的作用——>
抽象方法:没有方法体的方法
抽象类:一个类中如果有一个抽象方法
public abstract class Mammal {
public abstract void move() ;
}
一、抽象类
1、抽象类有构造方法,但是不能创建对象
2、如果一个类没有重写完父类中的所有抽象方法,则该类必须为抽象类
3、抽象类中可以没有抽象方法
public abstract class Mammal {
public void move() {
System.out.println("...");
}
}
4、
4、总结抽象类与普通类区别:
a、抽象类有abstract 修饰 普通类没有
b、抽象类不能创建对象,普通类可以创建对象
c、抽象类中可以有抽象方法,普通类绝对不能有抽象方法
思考:
1、abstract final class Mammal{ } 能编译通过吗, why?
答案是不能的,如图
原因:如果抽象类前面可以添加final就意味着该类无法被继承,也就意味着该抽象类中的抽象方法永远无法得到实现,也就意味着抽象类中的抽象方法是无用的。
2、Mammal抽象类中move抽象方法的访问权限可以为private吗,即“private abstract void move();”, why?
答案是不可以,如图
原因:被private修饰的方法其作用范围为本类,如果抽象类中的抽象方法被private修饰就意味着该方法永远无法被实现。
3、Mammal抽象类中move抽象方法可以由static修饰吗,,即“public static abstract void move();” why?
答案是不可以
原因:抽象类中的抽象方法如果可以被static修饰就意味着可以使用抽象类的类名来使用该方法,但是该抽象方法没有方法体,不具有使用的价值,所以Java中规定抽象类中不能包含被static修饰的静态抽象方法。
二、接口
1、定义:如果一个抽象类中都是抽象方法,则可以将该抽象类定义成接口 interface
注:接口一般以I开头,这样做使代码更加规范,增加了代码的可读性
2、接口中的抽象方法必须通过一个类来实现 implements 实现
接口实现类:一个实现了接口中抽象方法的类,因为Whale类实现了接口中抽象方法,所以Whale类即是实现类
public interface IMammal {//注意没有class
public abstract void move() ;
public abstract void eat() ;
}
public class Whale implements IMammal {
@Override
public void eat() {
// TODO Auto-generated method stub
}
@Override
public void move() {
System.out.println("靠鳍游动......");
}
}
接口注意事项
1、前面已提及接口一般以I开头
2、类似抽象类,如果一个类没有实现接口中的所有抽象方法,则该类必须为抽象类
3、接口中没有默认构造方法,而且也不能定义构造方法
4、接口中的变量为public static final常量,所以可以用类名调用,但不可二次定义赋值
(黄框左上角S F指的是static final)
5、接口中的抽象方法默认public abstract
所以接口里的方法可以不用写public abstract,如
public interface IMammal {
void move() ;
void eat() ;
int age = 12;
}
3、抽象类与接口区别
| 抽象类 | 接口 |
关键字 | abstract | Interface |
成员变量 | 可包含任意合法成员变量(包括各种访问级别的类成员变量和实例成员变量) | 只能包含公开静态常量(默认由public static final修饰) |
构造方法 | 有构造方法 | 无构造方法 |
方法 | 可包含任意合法方法(包括各种访问级别的非抽象类方法和非抽象实例方法,也包含除private外的非静态抽象方法) | JDK7及其以下版本JDK只能包含公开且抽象的方法(默认由public abstract修饰),而JDK8开始可以包含default、static修饰的非抽象方法。 |
如何实现抽象方法 | 通过自定义类继承抽象类的方式实现抽象类的抽象方法 | 通过自定义类implements接口实现接口中的抽象方法,定义类可以implements多个接口 |
是否存在多继承 | 一个抽象类只能继承一个抽象或非抽象类 | 一个接口可以继承多个接口 |