在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
在 Java 中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。
抽象类的特点
1 抽象类不能被实例化
2 抽象类是用来被继承的
3 可以通过多态来访问其中的成员
抽象方法的特点
1 使用abstract关键字修饰
2 抽象方法不能有方法体
3 抽象方法是用来被重写的。
抽象类和抽象方法的关系
1 抽象类可以没有抽象方法
2 包含抽象方法的类一定是抽象类
抽象类的子类
抽象类的子类 要么是抽象类 要么就重写父类中的所有的抽象方法
抽象类的成员特点
成员变量:变量 常量
构造方法:有
构造方法存在的意义:就是方便子类去使用父类的成员数据
成员方法:抽象方法:限定子类中必须完成的一些特定的功能
非抽象方法:提高了代码的复用性
模板模式
抽象类体现的就是一种模板模式的设计,抽象列作为多个子类的通用模板,子类在抽象了的基础上进行扩展,改造,但是子类总体上会保留抽象类的行为方式。
解决问题:
当功能内部一部分实现是确定,一部分的实现时不确定,可以把不确定的部分 暴露出去 让子类区实现。
模板模式:在软件设计开发中,对于一个算法而言,整体步骤是固定的,通用,这些步骤我们就可以定义在父类中,但是其中某一些部分是易变的,此时可以将易变的部分抽取出来,定义成抽象,让子类来实现。
抽象类总结规定
-
抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
-
抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
-
抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
-
构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
-
抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
接口
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口与类相似点:
1.一个接口可以有多个方法。
2.接口文件保存在 .java 结尾的文件中,文件名使用接口名。
3.接口的字节码文件保存在 .class 结尾的文件中。
4.接口相应的字节码文件必须在与包名称相匹配的目录结构中。
接口与类的区别:
1.接口不能用于实例化对象。
2.接口没有构造方法。
3.接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
4.接口不能包含成员变量,除了 static 和 final 变量。
5.接口不是被类继承,而是要被类实现。
6.接口支持多继承。
接口特性
接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
抽象类和接口的区别
- 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
- 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
实现一个接口的语法,可以使用这个公式:
接口语法:
...implements 接口名称[, 其他接口名称, 其他接口名称..., ...]
接口的多继承
在Java中,类的多继承是不合法,但接口允许多继承。
在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。
内部类
class 外部类{
修饰符 class 内部类{
}
}
内部类可以直接访问外部类的成员 包括私有成员
外部类要访问内部类的成员 必须创建对象
成员内部类
根据内部类定义的位置:定义在类中,和方法是同一级别
在外部内创建成员内部类的对象格式:
外部类.内部类 内部类对象名 = new 外部类().new 内部类();
成员内部类的使用;
将一个类设计为内部类的目的 ,大多数都是不想外界访问,所以内部类的定义应该私有化,私有化之后 在提供一个可以让外界调用的方法,方法内部常见内部类对象并调用
局部内部类
局部内部类是定义在方法中的类
对于局部内部类 在他所在的方法之外是无法访问的。他的访问的范围仅限于他所在的方法。在方法内要访问 需要创建内部类的对象
匿名内部类
匿名内部类的前提:
存在一个类或者接口,这里的类可以使抽象类也可以是具体类
匿名内部类:
格式:new 类名(){
重写的方法
}
new 接口名(){
实现方法
}
如:
public class DaoTest{
public static void main(String[] args) {
DaoTest daoTest = new DaoTest();
daoTest.test(new Dao() {
@Override
public void add() {
System.out.println("匿名内部类实现....");
}
});
}
public void test(Dao dao ){
dao.add();
}
}