Java内部类

1.内部类

概述:

把类定义在其他类的内部,这个类就被称为内部类。

举例:在类A中定义了一个类B,类B就是内部类。

内部类位置:

  • 成员位置(成员内部类)
  • 局部位置(局部内部类)

内部类的种类:

  • 成员内部类  ----成员变量
  • 静态成员内部类  --静态成员变量
  • 局部内部类  --局部变量
  • 匿名内部类

内部类的访问特点:

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

2、外部类要访问内部类的成员,必须创建对象。

2.成员内部类

外界如何创建内部类对象?

外部类名.内部类名 对象名 = 外部类对象.内部类对象;

外部类名.内部类名 inner = new 外部类().new 内部类();

 

成员内部类的修饰符  --->  成员变量

基本上成员变量和成员方法能用的修饰符成员内部类都可以用

例如:四种权限修饰符、staticfinalabstracter

 

代码:

class Demo1_InnerClass {
public static void main(String[] args) {
//Inner i = new Inner();
//i.method();
//外部类名.内部类名 = 外部类对象.内部类对象
Outer.Inner oi = new Outer().new Inner(); //创建内部类对象
oi.method();

}
}
class Outer {
private int num = 10;
class Inner {
public void method() {
System.out.println(num);
}
}
}

3.局部内部类

可以直接访问外部类的成员

可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能

 

局部内部类如何使用内部类创建对象?

   直接在成员方法内部位置创建该内部类对象并使用

局部内部类访问局部变量的注意事项:

必须被final修饰!

为什么?

因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。

代码:

class Demo1_InnerClass {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
//局部内部类
class Outer {
public void method() {
final int num = 10;
class Inner {
public void print() {
System.out.println(num);
}
}

Inner i = new Inner();
i.print();
}

/*public void run() {
Inner i = new Inner(); //局部内部类,只能在其所在的方法中访问
i.print();
}*/
}

4.静态内部类

   成员内部类被static修饰后外界如何创建对象

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

 外部类名.内部类名 inner3 = new 外部类.内部类();
代码:
class Demo1_InnerClass {
public static void main(String[] args) {
//外部类名.内部类名 对象名 = 外部类名.内部类对象;
Outer.Inner oi = new Outer.Inner();
oi.method();

Outer.Inner2.print();
}
}

class Outer {
static class Inner {
public void method() {
System.out.println("method");
}
}

static class Inner2 {
public static void print() {
System.out.println("print");
}
}
}

5.匿名内部类

匿名内部类就是内部类的简化写法。其本质是一个继承了类或者实现了接口的子类匿名对象。

 

使用前提:存在一个类或者接口(这里的类可以是具体类也可以是抽象类)。

 

本质:匿名内部类是一个接口或者抽象类的实现类或者子类的对象!

格式:

new 类名或者接口名() {

  重写方法;

}

匿名内部类在开发中的使用

首先回顾我们曾经讲过的方法的形式参数是引用类型的情况,重点是接口的情况,我们知道这里需要一个子类对象。而匿名内部类就是一个子类匿名对象,所以,可以使用匿名内部类改进以前的做法。

代码1:

public class Test2 {
public static void main(String[] args) {
//多态
// A a = new B();
// a.method();

//使用A接口的匿名内部类
//创建匿名内部类对象
A a = new A() {
@Override
public void method() {
System.out.println("匿名内部类");
}
};
a.method(); // 匿名内部类

//匿名内部类的形式创建抽象类对象
C c = new C() {
@Override
public void method() {
System.out.println("抽象类对象");
}
};
c.method(); //抽象类对象
method(a); //匿名内部类
method(new A() {
@Override
public void method() {
System.out.println("A");
}
}); //A
}

public static void method(A a) {
a.method();
}
}

interface A {
public void method();
}

class B implements A {

@Override
public void method() {
System.out.println("b");
}
}

abstract class C {
public abstract void method();
}

代码2:

class Test1_NoNameInnerClass {
public static void main(String[] args) {
//如何调用PersonDemo中的method方法呢?
PersonDemo pd = new PersonDemo ();
//pd.method(new Student());
pd.method(new Person() {
public void show() {
System.out.println("show");
}
});
}
}
//这里写抽象类,接口都行
abstract class Person {
public abstract void show();
}

class PersonDemo {

//public void method(Person p) { //Person p = new Student(); //父类引用指向子类对象
/*
Person p = new Person(){
public void show() {
System.out.println("show");
}
};
*/
public void method(Person p) {
p.show();
}
}

class Student extends Person {
public void show() {
System.out.println("show");
}
}

5.内部类的作用

1、 隐藏类的实现细节

 

 

2、 可以无条件的访问外部类的成员

 

 

3、过内部类可以实现多重继承

 

在内部类中,当成员内部类的成员变量或成员方法和外部类同名时该如何访问?

1、 访问内部类的成员变量和成员方法

2、 访问外部类的成员变量和成员方法

 代码:

package com.southwind.test;

/**
* 内部类的位置:
* 内部类的访问---内部类造对象
* 成员内部类造对象
*
* 内部类可以没有任何条件的访问外部类的成员
*/
class Outer {
private int num = 10;
public void method2(){
System.out.println("method2...");
//外部类中访问内部类中的成员
//必须创建内部类对象
//成员内部类对象如何创建
Inner inner = new Inner();
System.out.println(inner.i);
Inner3 inner3 = new Inner3();
}
public static int num2;

//静态内部类
public static class Inner3 {
public void method(){
//静态的成员不能访问非静态的
// System.out.println(num);
// method2();
}
}

//成员内部类---成员位置
public class Inner {
int i = 1;
public void method(){
System.out.println(num);
method2();
}
}

public void method() {
// int num;
//局部内部类
class Inner2 {
public void method(){
System.out.println(num);
method2();
}
}
//局部内部类只能在局部范围内使用
Inner2 inner2 = new Inner2();
inner2.method();
}
}

public class Test {
public static void main(String[] args) {
//创建外部类对象,都是在外部类外部


//成员内部类造对象
Outer.Inner inner = new Outer().new Inner();
//格式:外部类名.内部类名 inner = new 外部类().new 内部类();
inner.method();
// System.out.println(inner.i);

//静态内部类造对象
Outer.Inner3 inner3 = new Outer.Inner3();
//格式:外部类名.内部类名 inner3 = new 外部类.内部类();

//创建外部类对象
//调用方法
//执行局部内部类对象的方法
Outer outer = new Outer();
outer.method();
}
}
posted @ 2021-07-11 18:03  蔡地像徐坤  阅读(48)  评论(0编辑  收藏  举报