欢迎光临
我们一直在努力

15-内部类

  • 内部类
    • 什么是内部类
    • 为什么有内部类
    • 内部类的分类
    • 成员内部类
      • 编写成员内部类的注意事项
      • 如何创建成员内部类的对象
      • 成员内部类如何获取外部类的成员变量
    • 静态内部类
      • 创建静态内部类的对象的格式
      • 调用静态内部类中非静态方法的格式
      • 调用静态内部类中静态方法的格式
      • 示例2
    • 局部内部类
      • 示例
    • 匿名内部类
      • 作用
      • 使用场景
      • 定义格式
      • 示例

配套完整代码:GitHub仓库 https://github.com/LIN-commit/java-learning 代码所在目录:java-learning/innerclass/

内部类

什么是内部类

在一个类里面,再定义一个类

public class Outer{//外部类
public class Inner{//内部类

}
}

为什么有内部类

  • 需求:写一个Javabean类描述汽车
  • 属性:汽车的品牌,车龄,颜色,发动机的品牌,发动机的使用年限

public class Car{//外部类:汽车
String carName;
int carAge;
int carColor;
class Engine{//内部类:发动机
String engineName;
int engineAge;
}
}

注意

  • 内部类表示的事物是外部类的一部分
  • 内部类单独出现没有任何意义

内部类的分类

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类

成员内部类

写在成员位置的,属于外部类的成员(刚才代码中的class Engine就是成员内部类)

编写成员内部类的注意事项

  • 成员内部类可以被一些修饰符所修饰,比如:private(只在本类中使用),默认(只在本包中使用),protected(在本包和其他包的子类中使用),public(所有包都可以使用)等
  • 在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量

如何创建成员内部类的对象

  • 方式一:直接创建 格式:

外部类名.内部类名 对象名 = new 外部类名().new 内部类名();

示例:

Outer.Inner oi = new Outer().new Inner();

  • 方式二:外部类编写方法,对外提供内部类对象 例如:如果内部类用private修饰,那就无法直接创建。 对应package:Test1 对应代码:
  • Outer.java
  • Test.java

package Test1;

public class Outer {
String name;

private class Inner{

}
public Inner getInstance(){
return new Inner();
}
}

package Test1;

public class Test {
public static void main(String[] args) {
Outer o = new Outer();
System.out.println(o.getInstance());
}
}

[运行结果]

Test1.Outer$Inner@4e50df2e

打印的是对象的地址值,且

符前是外部类名,

符前是外部类名,

符前是外部类名,符后是内部类名

成员内部类如何获取外部类的成员变量

示例 对应package:Test2 对应代码:

  • Outer.java
  • Test.java

package Test2;

public class Outer {
private int a = 10;

class Inner{
private int a = 20;
public void show(){
int a = 30;
System.out.println(a);//30
System.out.println(this.a);//20
System.out.println(Outer.this.a);//10
}
}
}

package Test2;

public class Test {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}

[运行结果]

30
20
10

Outer.this表示获取了外部类对象的地址值

静态内部类

  • 静态内部类实际上是成员内部类的一种,只是要用static修饰
  • 静态内部类只能访问外部类中的静态变量和静态方法

示例:

public class Car{//外部类
String carName;
int carAge;
int carColor;
static class Engine{//静态内部类
public void show(){
sout(carName);//这样会报错,静态内部类无法直接访问外部类中非静态的内容
}
}
}

  • 如果在静态内部类中,需要访问外部类找那个非静态的内容,需要创建外部类的对象

这个知识点和之前学过的静态方法比较类似,静态只能访问静态 示例:

public class Car{
String carName;
int carAge;
int carColor;
public static void show(){//静态方法
sout("只能访问静态变量");
}
}

示例: 对应package:Test3 对应代码:

  • Outer1.java

package Test3;

public class Outer1 {
int a = 10;
static int b = 20;

//静态内部类
static class Inner{
//非静态的方法
public void show1(){
//System.out.println(a);//报错
Outer1 o = new Outer1();
System.out.println(o.a);
System.out.println(b);
}
//静态方法
public static void show2(){
//System.out.println(a);//报错
Outer1 o = new Outer1();
System.out.println(o.a);
System.out.println(b);
}
}
}

创建静态内部类的对象的格式

外部类名.内部类名 对象名 = new 外部类名.内部类名();

调用静态内部类中非静态方法的格式

先创建对象,用对象调用

调用静态内部类中静态方法的格式

外部类名.内部类名.方法名();

示例2

对应package:Test3 对应代码:

  • Outer.java
  • Test.java

package Test3;

public class Outer {
static class Inner{
//非静态的方法
public void show1(){
System.out.println("非静态的方法被调用了");
}
public static void show2(){
System.out.println("静态方法被调用了");
}
}
}

package Test3;

public class Test {
public static void main(String[] args) {
Outer.Inner oi = new Outer.Inner();
//调用非静态的方法
oi.show1();
//调用静态方法
Outer.Inner.show2();
}
}

[运行结果]

非静态的方法被调用了
静态方法被调用了

局部内部类

  • 将内部类定义在方法里面就叫作局部内部类,类似于方法里面的局部变量
  • 外界是无法直接使用,需要在方法内部创建对象并使用
  • 该类可以直接访问外部类的成员,也可以访问方法内的局部变量

示例

对应package:Test4 对应代码:

  • Outer.java
  • Test.java

package Test4;

public class Outer {
int a = 20;
public void show(){
int b = 10;
class Inner{
String name;
int age;
public void method1(){
System.out.println(a);
System.out.println(b);
System.out.println("调用局部内部类的method1方法");
}
public static void method2(){
System.out.println("调用局部内部类的静态方法method2");
}
}
Inner i = new Inner();
System.out.println(i.name);
System.out.println(i.age);
i.method1();
Inner.method2();
}
}

package Test4;

public class Test {
public static void main(String[] args) {
Outer o= new Outer();
o.show();
}
}

[运行结果]

null
0
20
10
调用局部内部类的method1方法
调用局部内部类的静态方法method2

匿名内部类

就是一个没有名字的内部类

作用

在继承一个类或者实现一个接口的时候少写一个文件,也是lambda的前置知识点

使用场景

如果实现类只要使用一次,就可以用匿名内部类简化代码

定义格式

new 类名或者接口名(){
重写方法;
};

示例

new Inter(){
public void show(){
...
}
};

示例

对应package:Test5 对应代码:

  • Swim.java
  • Test.java

package Test5;

public interface Swim {
public abstract void swim();
}

package Test5;

public class Test {
public static void main(String[] args) {
Swim s= new Swim(){
@Override
public void swim() {
System.out.println("学生去游泳");
}
};
goSwimming(s);
s.swim();
}
public static void goSwimming(Swim s ){
s.swim();
}
//用静态方法goSwimming来调用,是为了演示面向接口编程、多态和代码复用的思想
}

[运行结果]

学生去游泳
学生去游泳

) { Swim s= new Swim(){ @Override public void swim() { System.out.println(“学生去游泳”); } }; goSwimming(s); s.swim(); } public static void goSwimming(Swim s ){ s.swim(); } //用静态方法goSwimming来调用,是为了演示面向接口编程、多态和代码复用的思想 }

[运行结果]
```text
学生去游泳
学生去游泳

以上就是java内部类的内容了。下一篇我们将学习创建API,欢迎继续关注蓝猫学姐的java学习笔记~

赞(0)
未经允许不得转载:171主机测评 » 15-内部类
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址