在Java复习(2)中,发现对内部类的不太理解。特意针对性整理下。
1.什么是内部类(what)
1.1 定义
就是类的内部再定义类,就叫做内部类。
例1内部类定义,代码如下:
/*
* 内部类的访问特定:
* 1.内部类可以之间访问外部类的成员,包括私有。
* 2.外部累要访问内部类的成员,必须创建对象。
*/
//内部类定义
class Outer{
private int num = 10;
class Inner{
public void show(){
System.out.println(num);
}
}
//外部类调用内部类
public void method(){
//show();//这样会报错,不能直接使用
//正确的调用方式:
Inner i = new Inner();
i.show();
}
}
public class InnerClassDemo {
public static void main(String[] args){
Outer a = new Outer();
a.method();
}
}
运行结果:
10
1.2 内部类分类
内部类放在不同的位置,有所不同。
内部类放的位置有2种:
1.成员位置:在成员位置定义的类,被称为成员内部类
2.局部位置:在局部位置定义的类,被称为局部内部类
2.为什么要有内部类(why)
举个例子:人的体内有心脏。这里人是一个类,心脏也是一个类。但是心脏一定再人里面。所以就有了内部类。
3.如何使用内部类(how)
内部类放在不同的位置,会有不同的使用方法。
这里介绍,成员内部类和局部内部类2种方法。
3.1 成员内部类
内部类的访问特点:
1.内部类可以之间访问外部类的成员,包括私有。
2.外部累要访问内部类的成员,必须创建对象。
3.1.1 最简单的成员内部类写法
例2:最简单的成员内部类写法
/*
* 成员内部类
*/
class Outer1{
private int num = 10;
class Inter{
public void show(){
System.out.println(num);
}
}
}
public class InnerClassDemo2 {
public static void main(String[] args){
//访问内部类的格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer1.Inter a = new Outer1().new Inter();
a.show();
}
}
运行结果:
10
3.1.2 成员内部类的修饰符
成员内部类的修饰符常见2种:
1.private(因为内部类一般不让直接访问)
2. static(注意静态内部类访问的外部类数据必须用静态)
例3:private修饰内部类
/*
* 创建一个类,要求:我有一个人,人有身体,身体内有心脏。
*/
class Body{
//用private修饰的内部类
private class Heart{
public void operator(){
System.out.println("心脏搭桥");
}
}
}
public class InnerClassDemo3 {
public static void main(String[] args){
Body.Heart bh = new Body().new Heart();
bh.operator();
}
}
运行结果:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The type Body.Heart is not visible
The type Body.Heart is not visible
The type Body.Heart is not visible
at com.xxm.javaLange.test.InnerClassDemo3.main(InnerClassDemo3.java:20)
所以说明加了private修饰的内部类,调用方法不同。
正确但调用方法,例子4:
class Body{
//用private修饰的内部类
private class Heart{
public void operator(){
System.out.println("心脏搭桥");
}
}
//用外部类中的方法才能调用
public void method(){
Heart h = new Heart();
h.operator();
}
}
public class InnerClassDemo3 {
public static void main(String[] args){
Body a = new Body();
a.method();
}
}
运行结果:
心脏搭桥
例子5:static修饰内部类
package com.xxm.javaLange.test;
class Outer2{
private int num = 10;
private static int num2 = 100;
//内部类用静态修饰,为了可以用外部访问,所以也不会加上private,而是用public修饰
public static class Inner{
//非静态方法
public void show(){
//System.out.println(num);//直接调用num会报错,因为静态类只能访问静态变量,所以调用num2才正确
System.out.println(num2);
}
//静态方法
public static void show2(){
System.out.println(num2);
}
}
}
public class InnerClassDemo4 {
public static void main(String[] args){
//错误的调用方法
// Outer2.Inner a = new Outer2().new Inner();//new Outer2()是创建对象,Inner是静态的,不能被类调用
// a.show();
// a.show2();
//调用方法
Outer2.Inner b = new Outer2.Inner();
b.show();
b.show2();
//show2的另一种调用方法
Outer2.Inner.show2();
}
}
运行结果:
100
100
100
3.2 局部内部类
局部内部类就是放在类的方法里面的内部类。
3.2.1 局部内部类定义
例6:局部内部类定义
/*
* 局部内部类
*/
class Outer3{
private int num = 10;
public void method(){
//局部内部类
class Inner{
public void show(){
System.out.println(num);
}
}
Inner i = new Inner();
i.show();
}
}
public class InnerClassDemo5 {
public static void main(String[] args){
Outer3 a = new Outer3();
a.method();
}
}
运行结果:
10
3.2.2 局部内部类访问局部变量
例7:局部内部类访问局部变量
class Outer3{
private int num = 10;
public void method(){
final int num2 = 20;
/*
* 局部内部类如何访问局部变量,一定要加final。
* 因为局部变量会随着method方法的调用结束而消失,
* Inner类放在堆内存中,不会因为method的结束而结束,
* 调用num2时候,其实际已经消失,所以加上final,作为常量
*/
//局部内部类
class Inner{
public void show(){
System.out.println(num);
System.out.println(num2);
}
}
Inner i = new Inner();
i.show();
}
}
public class InnerClassDemo5 {
public static void main(String[] args){
Outer3 a = new Outer3();
a.method();
}
}
运行结果:
10
20
3.2.3 匿名内部类
下面举4个例子。
例8:匿名内部类中一个方法时
interface Inter{
public abstract void show();
}
class Outer4{
public void method(){
new Inter(){
//一个方法
public void show(){
System.out.println("show");
}
}.show();
}
}
public class InnerClassDemo6 {
public static void main(String[] args){
Outer4 a = new Outer4();
a.method();
}
}
运行结果:
show
例9:匿名内部类中2个方法时
interface Inter{
public abstract void show();
public abstract void show2();
}
class Outer4{
public void method(){
new Inter(){
//第一个方法
public void show(){
System.out.println("show");
}
//第二个方法
public void show2(){
System.out.println("show2");
}
}.show();//调用第一个方法
//因为匿名对象只能调用一次,所以只能重新调用
new Inter(){
//第一个方法
public void show(){
System.out.println("show");
}
//第二个方法
public void show2(){
System.out.println("show2");
}
}.show2();//调用第二个方法
}
}
public class InnerClassDemo6 {
public static void main(String[] args){
Outer4 a = new Outer4();
a.method();
}
}
运行结果:
show
show2
例10:匿名内部类中有多个方法
例子里是3个方法
interface Inter{
public abstract void show();
public abstract void show2();
public abstract void show3();
}
class Outer4{
public void method(){
Inter i = new Inter(){//多态
public void show(){
System.out.println("show");
}
public void show2(){
System.out.println("show2");
}
public void show3(){
System.out.println("show3");
}
};
i.show();
i.show2();
i.show3();
}
}
public class InnerClassDemo6 {
public static void main(String[] args){
Outer4 a = new Outer4();
a.method();
}
}
运行结果:
show
show2
show3
例10:匿名内部类在开发中多使用
interface Person{
public abstract void study();
}
class PersonDemo{
public void method(Person P){
P.study();
}
}
public class InnerClassDemo7 {
public static void main(String[] args){
//用匿名内部类使用
PersonDemo pd = new PersonDemo();
pd.method(new Person(){
/*
*优点:能随着method方法的结束而被回收内存,
*适合安卓上的开发。
*缺点:每次使用都要new一下,
*若使用多次,就不建议这样用类。
*/
public void study(){
System.out.println("好好学习!");
}
});
}
}
运行结果:
好好学习!