关键字abstract抽象
作用于
可以用来修饰:类、方法
abstract修饰类:抽象类
- 该类不能实例化,即不能创建对象
- 抽象类一般都为父类,其一定有构造器,便于子类实例化时调用
- 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作—>抽象的使用前提(继承性)
abstract修饰方法:抽象方法
- 抽象方法只有方法的声明,没有方法体
- 包含抽象方法的类一定是抽象类,反之,抽象类不一定就有抽象方法
- 若子类希望实例化,则需要将所有父类中的抽象方法都重写才可以
- 若子类没有重写所有,则需要将子类转为抽象类,添加abstract
注意点
-
abstract不能修饰 属性、构造器 等结构
-
abstract不能用来修饰 私有方法、静态方法、final的方法、final的类
-
因为子类需要重写父类的abstract的方法,而private修饰的方法不允许被重写
-
子类要想重写父类中同名同参数的方法 必须 子类父类都是非静态的 ;
总之需要子类父类同时保持一致,要么都静态,要么都非静态
-
final修饰的方法不允许重写,与abstract正好相反
-
final修饰的类不允许有子类,与abstract正好相反
-
具体应用
举例一
举例二
abstract class GeometricObject{
public abstract double findArea();
}
class Circle extends GeometricObject{
private double radius;
public double findArea(){
return 3.14 * radius * radius;
}
}
举例三
IO流中设计到的抽象类:InputStream/OutputStream / Reader /Writer。
在其内部定义了抽象的read()、write()方法。
关键字interface接口
说明
- 接口使用interface来定义
- 在Java中,接口和类是并列的两个结构
public class plane{
}
interface flyable{
}
-
接口里可以定义什么结构
- JDK7及以前:只能定义全局常量和抽象方法
全局常量:public static final的,但是书写时,可以省略不写
抽象方法:public abstract的,但是书写时,可以省略不写
interface flyable{
public static final int SPEED = 10;//常量声明时是大写,常量是static
int SPEED_2 = 20;//前面的修饰可以不写,但意义都是一样的
public abstract void stop();//方法是abstract
void stop();
}
-
接口中不能定义构造器!!!会报错的,因此意味着接口不可以实例化
-
Java开发中,类通过实现(implement)的方式来使用接口
- 想要类实现实例化,则需要 **覆盖(实现)**接口中所有的抽象方法
- 若没有 覆盖 所有抽象方法,则需将该类转为 抽象类
-
Java类可以实现多个接口 —>弥补了Java单继承性的局限性
格式:class AA extends BB implements CC,DD,EE(先写 继承 再写 实现接口)
-
接口与接口之间可以继承,而且可以多继承
interface aa{
}
interface bb{
}
interface cc extends aa,bb{
}
- 接口的具体使用,体现多态性
public class InterfaceTest{
psvm{
Computer c = new Computer();
c.transferData(new Flash());//实现子类
c.transferData(new Printer());//实现子类
}
}
class Computer{
public void transferData(USB usb){//USB usb = new Flash();
usb.start();
System.out.println("具体传输数据的细节");
usb.stop();
}
}
interface USB{
//常量:定义了长、宽、最大最小的传输速度等
void start();
void stop();
}
class Flash implements USB{
@Override
public void start() {
System.out.println("U盘开启工作");
}
@Override
public void stop() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB{
@Override
public void start() {
System.out.println("打印机开启工作");
}
@Override
public void stop() {
System.out.println("打印机结束工作");
}
}
-
接口,实际上可以看作是一种规范,JDBC里定义了各种接口,调用各类数据库都得经过JDBC,统一了格式,也就是一种规范
面向接口编程:我们在应用程序中,调用的结构都是JDBC中定义的接口,不会出现具体某一个数据库厂商的API。
体会
- 接口使用上也满足多态性
- 接口,实际上就是定义了一种规范
- 开发中,体会面向接口编程!
Java8接口中新特性
JDK8中,interface里除了可以定义全局常量和抽象方法以外,还可以定义静态方法、默认方法
public interface Test{
//静态方法
public static void method1(){
Sout("1");
}
//默认方法
public default void method2(){
sout("2");
}
public default void method3(){
sout("3");
}
}
- 接口中定义的静态方法只能通过 **接口 **来调用.
Test.method1();
-
接口中定义的默认方法通过实现类的对象来调用
如果 实现类 中重写了接口中的 默认方法 ,调用时,仍然调用的是重写以后的方法
psvm{
SubClass s = new SubClass();
s.method2();//未重写
s.method3();//重写了
}
class SubClass extends SuperClass implements Test{
public void method3(){
sout("3");
}
}
-
如果子类(或 实现类) 继承的 父类 和 实现的接口 中声明了同名同参的默认方法,且 子类 没重写的情况下,默认调用的是父类中的方法 --> 体现了 类优先原则
-
如果 实现类 实现 多个接口,而多个接口定义了同名同参的 默认方法 ,且实现类没有重写该方法的情况下,则会报错
–> 体现了 接口冲突 ,此时就需要在 实现类 中重写该方法
-
如何在 子类(或 实现类)的方法中 调用 父类 或者 接口 中被重写的方法
class SuperClass{
public void method4(){
sout("4");
}
}
class SubClass extends SuperClass implements Test{
public void method3(){
sout("3");
}
public void myMethod(){
method3();//调用自己定义的重写的方法
super.method4();//调用的是父类中声明的
Test.super.method3();//调用接口中的默认方法,注意格式
}
}