目录
引言
在Java中,接口(Interface)和内部类(Inner Class)是两个非常重要的概念,它们在面向对象编程中扮演着关键角色。本文将详细解析Java中的接口和内部类,并通过代码示例进行说明。
一、接口(Interface)
接口是一种引用类型,是Java实现多继承的一种机制。它定义了一组方法规范,但不提供这些方法的具体实现。接口中的方法默认是public abstract的,即公开的、抽象的。接口主要用于定义对象的行为,而不是实现这些行为。
1.1 接口的定义
接口使用interface关键字来定义,其基本语法如下:
public interface InterfaceName {
// 常量定义
public static final int CONSTANT = 10;
// 抽象方法定义
void method1();
void method2();
// Java 8+ 默认方法
default void defaultMethod() {
// 默认实现
}
// Java 8+ 静态方法
static void staticMethod() {
// 静态实现
}
}
1.1.1 接口的特点
①成员变量
只能是常量
默认修饰符:public static final
②构造方法
没有
③成员方法
默认是抽象方法
默认修饰符:public abstract
JDK7以前:接口中只能定义抽象方法
JDK8的新特性:接口中可以定义有方法体的方法(默认方法:关键字default修饰)
JDK9的新特性:接口中可以定义私有方法
1.2 接口的实现
类通过implements关键字来实现接口,并实现接口中定义的所有抽象方法。如果类没有实现接口中的所有方法,则该类必须声明为抽象类。
public class ClassName implements InterfaceName {
@Override
public void method1() {
// 实现方法1
}
@Override
public void method2() {
// 实现方法2
}
}
1.3 接口的继承
接口可以继承其他接口,使用extends关键字。一个接口可以继承多个接口,这是Java实现多继承的主要方式。
public interface InterfaceA {
void methodA();
}
public interface InterfaceB extends InterfaceA {
void methodB();
}
public class ClassC implements InterfaceB {
@Override
public void methodA() {
// 实现方法A
}
@Override
public void methodB() {
// 实现方法B
}
}
1.4 接口的注意事项
- 接口不能被实例化。
- 接口中的方法默认是public abstract的,可以省略public abstract修饰符。
- 接口中的变量默认是public static final的,即常量。
- 一个类可以实现多个接口。
- 接口之间可以单继承,也可以多继承。
- 多个接口里面有重名的方法,只需重写一次即可
- 接口与类之间是实现关系,通过implements关键字表示
1.5 代码示例
public interface Animal {
void eat();
void sleep();
}
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog is eating.");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping.");
}
}
public class Test {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.eat();
myDog.sleep();
}
}
二、内部类(Inner Class)
内部类是在一个类的内部定义的类。内部类可以访问外部类的所有成员(包括私有成员),而外部类则不能直接访问内部类的成员,除非通过内部类的对象。内部类主要有四种类型:成员内部类、静态内部类、局部内部类和匿名内部类。
2.1 内部类特点
访问特点:
①内部类可以直接访问外部类成员,包括私有。
②外部类要访问内部类的成员,必须创建对象 。
2.2 成员内部类
成员内部类定义在外部类的成员位置,可以访问外部类的所有成员(包括私有成员)。
public class OuterClass {
private int outerVar = 10;
public class InnerClass {
public void display() {
System.out.println("OuterVar = " + outerVar);
}
}
public InnerClass getInnerClassInstance() {
return new InnerClass();
}
}
public class Test {
public static void main(String[] args) {
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.getInnerClassInstance();
inner.display();
}
}
问题:当有多个同名变量时,代码中的__中填写什么才能打印以下结果?
class Outer
{
private int num = 1;
private class Inner
{
private int num = 2;
public void show()
{
int num = 3;
System.out.println(__); // 3
System.out.println(__); // 2
System.out.println(__); // 1
}
}
}
①打印3可以十分简单,根据就近原则,直接填入num即可
②类中都有一个this, 可以通过this.num去访问外部类的num,打印2
③内部类中访问外部类的同名成员变量,需要借助外部类名.this去访问,即可打印1
2.2.1 对象的创建
①当成员内部类被private修饰时:
在外部类编写方法,对外提供内部类对象
②当成员内部类被非private修士时:
直接创建对象
语法:外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
2.3 静态内部类
静态内部类使用static修饰符定义,可以通过外部类名直接访问,但它不能访问外部类的非静态成员。
public class OuterClass {
private static int outerVar = 10;
public static class StaticInnerClass {
public void display() {
System.out.println("OuterVar = " + outerVar);
}
}
}
public class Test {
public static void main(String[] args) {
OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass();
inner.display();
}
}
2.3.1 对象的创建
创建静态内部类的格式:
外部类名.内部类名 对象名 = 外部类名.内部类名();
2.4 局部内部类
局部内部类定义在外部类的方法内部,其作用域仅限于该方法内部。
public class OuterClass {
public void method() {
class LocalInnerClass {
public void display() {
System.out.println("This is a local inner class.");
}
}
LocalInnerClass inner = new LocalInnerClass();
inner.display();
}
}
// 注意:由于LocalInnerClass是局部内部类,它不能在method方法外部被访问。
2.5 匿名内部类
匿名内部类是没有类名的内部类,通常用于实现接口或继承其他类,并立即创建该类的实例。
2.5.1 格式
new 类名或接口名(){
重写方法;
}
①实现/继承关系
②方法重写
③创建对象
2.5.2 代码示例
public interface HelloWorld {
void greet();
}
public class Test {
public static void main(String[] args) {
HelloWorld greeting = new HelloWorld() {
@Override
public void greet() {
System.out.println("Hello, World!");
}
};
greeting.greet();
}
}
结语
接口和内部类是Java中非常重要的概念。接口定义了一组规范,用于实现多继承,而内部类则提供了一种将类定义在另一个类内部的方式,增强了代码的封装性和可读性。通过接口和内部类的使用,Java程序员可以编写出更加灵活、可维护的代码。