接口
使用关键字
interface
定义接口
public interface
会飞的
{
public
void
起飞
();
public
void
巡航飞行
();
public
void
降落
();
}
接口不能直接使用,必须有对应的实现类
public class
飞机类
implements
会飞的
{
//
共性是通过实现接口来表示的
private
String
name
;
//
名称,这是类属的属性,这里可以定义字节类的成员,和接口无关
//
如果当前类不是抽象类,则必须实现接口中的所有抽象方法
@Override
public
void
起飞
() {
System
.
out
.
println
(
"
使劲的跑,一抬头就飞起来了
"
);
}
@Override
public
void
巡航飞行
() {
System
.
out
.
println
(
"
使劲的烧油
..."
);
}
@Override
public
void
降落
() {
System
.
out
.
println
(
"
我对准
..."
);
}
}
通过接口定义变量,使用具体类的实例,进行调用
引入接口的目的在于隔离实现
使用接口而不是使用具体的类,则可以实现在实现接口的多个具体实现类之间进行更换
什么是接口
在
Java
中不直接支持多继承,因为会出现调用的不确定性,所以
Java
将多继承机制进行改良,在
Java
中
变成了多实现。一个类可以实现多个接口,一个接口可以继承多个接口
interface
IA
{}
interface
IB
{}
interface
IC
extends
IA
,
IB
{}
正确的,其中
IC
中的方法等于
IA
+
IB
class
A
implements
IA
,
IB
{}
IA a
=
new
A
();
IB b
=
new
A
();
接口是一种特殊的抽象类,接口只能被
abstract
或者
public
修饰
没有构造器方法
没有属性,只能定义常量
可以包含抽象方法,也可以没有抽象方法
接口中的方法只能被
public
、
default
、
abstract
、
static
修饰
一般情况下接口中只定义抽象方法
定义的方法默认为公开的抽象方法
抽象方法必须在实现类中提供实现
可以使用
default
关键字给抽象方法提供默认实现,有默认实现的方法在实现类中可以重新定义,也
可以不重新定义
接口允许多重继承
一个类在继承另一个类的同时,还可以实现多个接口
interface
IA1
{
public
void
p1
();
}
interface
IA2
{
public
void
p2
();
}
interface
IC
extends
IA1
,
IA2
{
public
void
p3
();
允许一个类实现多个接口
,
但是每个接口的抽象方法都必须提供实现,否则是抽象类。提供的实现也可以
是继承
接口的出现避免了单继承的局限性,这样定义
C
接口则拥有
A+B
的所有定义,可以使用
A
和
B
接口以及父
类
D
声明变量类型,直接
new T
。但是约束时,用谁声明变量编译器系统识别就是谁这种类型,也就意味
只能调用识别类型中的方法,不能调用其他方法
接口中没有属性,只能定义常量,它提供一些常量,实现它的类可以共享这些常量
接口可以给出访问控制符,用
public
修饰的是公共接口,到处可见;如果定义接口没有范围限定
词,则只能在同包中访问
接口中只能定义常量和抽象方法
接口中只能定义公共的常量,接口中的属性默认是
public static final
类型的,必须是
public static
final
类型的
接口不能被实例化,只能通过实现类所实现,但是可以用于声明变量的类型。
接口 变量名
=new
实现接口类
()
;
接口没有构造函数
接口中的抽象方法必须在非抽象子类中提供实现,这个实现可以是继承来的
interface
IA2
{
public
void
pp
();
}
class
A2
{
public
void
pp
() {
}
}
class
B2
extends
A2
implements
IA2
{
//
这里的
pp
方法的实现是从父类中继承来的
}
接口抽象方法的默认修饰符为
public
,在实现接口时必须用
public
关键字在方法头上说明
一个接口可以被多个子类实现。一个子类还可以实现多个接口
类实现接口
一个类在实现某接口的抽象方法时,必须使用完全相同的方法头
public
如果一个类实现多接口,用逗号隔开
如果一个类实现了声明相同方法的两个接口,则被多个接口共用
public class Test1 {
public static void main(String[] args) {
IA2 a2=new B2(); a2.pp();
IA3 a3=new B2(); a3.pp();
1
2
3
4
类在实现接口时可以定义它自己的附加成员,这也是最常见的形式
如果一个类不完全实现接口的所有方法,必须把类定义成
abstract
类型的类,任何继承该类的子类
必须实现该接口
接口中常量
可以为多个接口的实现类共享常量
如果一个类不完全实现接口的所有方法,必须把类定义成
abstract
类型的类,任何继承该类的子类
必须实现该接口
只需在接口中定义并赋值,此后不能再修改
在类中说明是接口的实现类,就可以使用该接口的常量了
一个类只能有一个父类!
一个类可以实现多个接口!
一个接口可以继承多个接口
接口和抽象类的异同点
相同点:都是不断向上抽取而来的
不同点:
抽象类需要被继承,而且只能单继承
接口需要被实现,而且可以多实现
抽象类中可以定义抽象方法和非抽象方法,子类继承后可以直接使用非抽象方法
接口中可以定义抽象方法和
default
方法,抽象方法必须由子类去提供实现;
JDK1.8+
中允许接口中
的方法有默认实现,实现类中可以直接使用默认实现,允许覆盖定义
抽象类的继承是
is a
关系,在定义该体系的基本共性内容
接口的实现是
like a
关系,在定义体系额外功能
接口中只能定义常量,而且必须被初始化,抽象类中可以定义属性,允许在声明时直接初始化,也
可以不初始化,同时允许定义常量
接口中的公共方法应该全部是抽象的,
JDK1.8+
版本中可以通过
default
关键字定义方法的默认实现,允
许定义静态方法,
JDK1.9
开始可以定义私有方法;抽象类中可以有抽象方法也可以有普通方法
从设计层面看,抽象类体现继承关系
is a
,它主要描述类的从属关系或者父子关系,抽象类和它的派生类
之间是典型的
IS-A
关系,即子
is a
父。
interface
可以多实现,而且不要求实现者和
interface
定义在概念本质上是一致的,仅仅是实现了
interface
定义的契约而已。它主要描述的是类型间的行为合同,接口和它的实现类之间是典型的
CAN
DO
关系,即子
can do
父。
为什么接口需要默认方法
在接口添加默认方法不需要修改实现类,接口新增的默认方法在实现类中直接可用。
另外还要注意默认方法冲突问题。
内部类
一个类或者接口定义在另外一个类后者接口的内部
public class
A1
{
//
外部类
class
B1
{}
//
内部类
interface
C1
{}
//
内部接口
}
将一个类定义置入另一个类定义中,这就叫作
“
内部类
”
内部类之外的类称为外部类
内部类的名称必须区别于它所在的外部类,和其它类之间没有要求
内部类可以访问其外部类的所有变量和方法
外部类不能直接访问内部类的实现细节
内部类比外部类多了
private/protected/static
三个修饰符,这三个修饰符不能用在外部类上
非静态内部类不能拥有静态成员
内部类的作用
内部类提供更好的封装
内部类可以直接访问外部类的私有成员
外部类不能直接访问内部类的成员,需要构建内部类对象才能访问
匿名内部类适合用于创建仅仅使用一次使用的类
分析事物时发现该事物描述还有事物,而且这个事物还在访问被描述事物的内容
例如牛和牛腿
如果一个事物离开另外一个事物后则没有任何意义,这种情况下建议使用内部类,不允许其他类访
问
内部类能直接访问外部类中成员,是因为内部类持有了外部类的引用,即外部类名
.this
内部类分类
在
Java
中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的
内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。
内部类实际拥有外部类的一个引用,在构造函数中将外部类的引用传递进来。