内部类Java(内部类定义)

createh54周前 (02-01)技术教程19

概念

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类

什么时候使用内部类

一个事物内部还有一个独立的事物,内部的事物脱离外部的事物无法独立使用

比如汽车只有一个发动机,电脑只有一个CPU

内部类的分类

按定义的位置来分

1. 成员内部内,类定义在了成员位置 (类中方法外称为成员位置)

2. 局部内部类,类定义在方法内

成员内部类

成员内部类:定义在类中方法外的类。

格式

class 外部类 {

// 成员变量

// 成员方法


class 内部类 {

// 成员变量

// 成员方法

}

}

在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car中包含发动机类Engine,这时,Engine就可以使用内部类来描述,定义在成员位置。

示例

class Car { //外部类

class Engine { //内部类


}

}

访问特点

内部类可以直接访问外部类的成员,包括私有成员。

创建内部类对象格式:

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

示例

public class Body {
public boolean live = true;
public void walk() {
System.out.println("散散步");
}
class Heart {
public void jump() {
// 直接访问外部类成员
if (live) {
System.out.println("脚离地了");
} else {
System.out.println("智商又占领高地了");
}
}
}
}

测试类

public class Test {
public static void main(String[] args) {
// 外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
// 创建的是内部类对象
// Body.Heart heart = new Body().new Heart();
// heart.jump();
// 创建方式2:先创建外部类,再创建内部类
// 创建外部类对象
Body b = new Body();
// 创建内部类对象
Body.Heart heart = b.new Heart();
// 调用内部类方法
heart.jump();
// 调用外部类方法
b.live = false;
// 调用内部类方法
heart.jump();
}
}

局部内部类

局部内部类:定义在方法中的类。

格式

class 外部类名 {

数据类型 变量名;


修饰符 返回值类型 方法名(参数列表) {

// …

class 内部类 {

// 成员变量

// 成员方法

}

}

}

使用: 在定义好局部内部类后,直接就创建对象

访问特点

内部类可以直接访问外部类的成员,包括私有成员。

匿名内部类(重点)

匿名内部类:是内部类的简化写法。它的本质是一个带具体实现的父类或者父接口的匿名的子类对象。开发中,最常用到的内部类就是匿名内部类了。

之前我們使用接口时,似乎得做如下几步操作:

1. 定义子类

2. 重写接口中的方法

3. 创建子类对象

4. 调用重写后的方法

interface Swim {
public abstract void swimming();
}

// 1. 定义接口的实现类

class Student implements Swim {
// 2. 重写抽象方法
@Override
public void swimming() {
System.out.println("仰泳");
}
}

public class Test {
public static void main(String[] args) {
// 3. 创建实现类对象
Student s = new Student();
// 4. 调用方法
s.swimming();
}
}

我们的目的,最终只是为了调用方法,那么能不能简化一下,把以上四步合成一步呢?匿名内部类就是做这样的快捷方式。

匿名内部类前提

匿名内部类必须继承一个父类或者实现一个父接口

格式

new 父类名或者接口名(){

// 方法重写

@Override

public void method() {

// 执行语句

}

};

使用方式

示例

interface Swim {
public abstract void swimming();
}

// 1. 定义接口的实现类

class Student implements Swim {
// 2. 重写抽象方法
@Override
public void swimming() {
System.out.println("仰泳");
}
}

public class Test {
public static void main(String[] args) {
// 使用匿名内部类
new Swim() {
@Override
public void swimming() {
System.out.println("蛙泳");
}
}.swimming();
// 接口 变量 = new 实现类(); 多态,走子类的重写方法
Swim s2 = new Swim() {
@Override
public void swimming() {
System.out.println("游泳");
}
};
s2.swimming();
s2.swimming();
}
}

匿名内部类的本质

1. 定义一个没有名字的内部类

2. 这个类实现了Swim接口

3. 创建了这个没有名字的类的对象

匿名内部类的作用

简化代码

匿名内部类的使用场景

通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。示例:

interface Swim {
public abstract void swimming();
}


// 1. 定义接口的实现类

class Student implements Swim {
// 2. 重写抽象方法
@Override
public void swimming() {
System.out.println("仰泳");
}
}


public class Test {
public static void main(String[] args) {
// 普通方式传入对象
// 创建实现类对象
Student s = new Student();
goSwimming(s);
// 匿名内部类使用场景:作为方法参数传递
Swim s3 = new Swim() {
@Override
public void swimming() {
System.out.println("顾泳");
}
};
// 传入匿名内部类
goSwimming(s3);
// 完美方案: 一步到位
goSwimming(new Swim() {
public void swimming() {
System.out.println("小学生, 蛙泳");
}
});
goSwimming(new Swim() {
public void swimming() {
System.out.println("中学生, 潜泳");
}
});
}
// 定义一个方法,模拟请一些人去游泳
public static void goSwimming(Swim s) {
s.swimming();
}
}

相关文章

Java基础——面试官:你来说说反射如何获取私有对象的属性和方法

最近,@Python大星 的朋友小鹿参加了一场#Java#面试。有一道题是这样的 >>>【面试官问:你来说说反射如何获取私有对象的属性和方法?】问题的答案我们文章中揭晓,先看下反射的...

浅谈Java内省(java内存详解)

作者:京东物流 王国泰一、什么是内省讲内省,不得不说Java Bean,Bean在Java中是一种特殊的类,主要用于装载数据,数据会被存储在类的私有属性中,通常具有无参构造函数、可序列化、以及通过ge...

思考:Java对象之生(java中对象的概念的理解)

内存、性能是程序永恒的话题,实际开发中关于卡顿、OOM也经常是打不完的两只老虎,关于卡顿、OOM的定位方法和工具比较多,这篇文章也不打算赘述了,本章主要是来整理一下JVM的内存模型以及Java对象的生...

java匿名内部类的定义以及使用场景

匿名内部类定义 匿名内部类是Java中一种没有显式声明名称的内部类。它们在创建时被同时声明和实例化,通常用于创建一次性使用的类。它们的特点是:无名称: 无法像普通类一样被其他代码引用。一次性: 通常只...

java 核心技术-12版 卷Ⅰ- 6.1.4 静态和私有方法

原文6.1.4 静态和私有方法在 Java 8 中,允许在接口中增加静态方法。理论上讲,没有任何理由认为这是不合法的。只是这似乎有违于将接口作为抽象规范的初衷。目前为止,通常的做法都是将静态方法放在伴...