可以将一个类的定义放在里另一个类的内部,这就是内部类。广义上我们将内部类分为四种:成员内部类、静态内部类、局部(方法)内部类、匿名内部类。
二:使用内部类
(1)成员内部类
图(1),新建外部类,使用成员内部类
团(2)其他类使用成员内部类
图2运行结果:
成员内部类总结:
- 内部类的内部不能有静态信息。外部类如何访问内部类信息,必须new之后打点访问。
(2)静态内部类
package *******.test.inner.staticInner;
public class Outer {
private int outerAttribute = 1;
private int commonAttribute = 2;
private static int staticOuterAttribute = 3;
static {
System.out.println("外部类的静态代码快被执行了!");
}
private void outerMethod(){
System.out.println("外部类的普通方法被执行=========");
}
private static void staticOuterMethod(){
System.out.println("外部类的静态方法被执行=======");
}
public static class Inner{
private int innerAttribute = 10;
private int commonAttribute = 20;
private static int staticInnerAttribute = 30;
static{
System.out.println("内部类的静态代码快被执行了!");
}
public void innerShow() {
System.out.println("innerAttribute:" + innerAttribute);
System.out.println("内部的commonAttribute:" + commonAttribute);
System.out.println("staticOuterAttribute:"+staticOuterAttribute);
staticOuterMethod();
}
public static void innerStaticShow() {
//被调用时会先加载Outer类
staticOuterMethod();
// outerMethod();内部类方法只能访问外部为static修饰的方法
System.out.println("staticOuterAttribute"+staticOuterAttribute);
}
}
public static void callInner() {
System.out.println(Inner.staticInnerAttribute);
Inner.innerStaticShow();
}
}
package ********.test.inner.staticInner;
public class Other {
public static void main(String[] args) {
//访问静态内部类的静态方法,Inner类被加载,此时外部类未被加载,独立存在,不依赖于外围类。
Outer.Inner.innerStaticShow();
//访问静态内部类的成员方法
Outer.Inner oi = new Outer.Inner();
oi.innerShow();
}
}
输出结果:
内部类的静态代码快被执行了!
外部类的静态代码快被执行了!
外部类的静态方法被执行=======
staticOuterAttribute3
innerAttribute:10
内部的commonAttribute:20
staticOuterAttribute:3
外部类的静态方法被执行=======
局部内部类总结:
- 静态内部类的方法只能访问外部类的static关联的信息。利用 外部类.内部类 引用=new 外部类.内部类(); 然后利用引用.成员信息(属性、方法)调用。
(3)局部内部类
package ***********.test.inner.part;
public class Outer {
public static void main(String[] args) {
Outer outer = new Outer();
outer.outerMethodCreate(1000);
}
private int outerAttribute = 1;
private int commonAttribute = 2;
private static int outerStaticAttribute = 3;
static {
System.out.println("外部类的静态代码块执行了。。。。。。。。。");
}
public void outerMethod(){
System.out.println("外部类普通方法,outerMethod===========================");
}
public static void outerMethodStatic(){
System.out.println("外部类静态方法,outerMethodStatic====================");
}
public void outerMethodCreate( int value){
boolean sex = false;
class Inner{
private int innerAttribute = 10;
private int commonAttribute = 20;
public void innerShow(){
System.out.println("innerAttribute: " + innerAttribute);
System.out.println("是否男性: " + sex);
System.out.println("参数value: " +value);
//调用外部类的信息
System.out.println("outerAttribute:" + outerAttribute);
System.out.println("内部的commonVariable:" + commonAttribute);
System.out.println("外部的commonVariable:" + Outer.this.commonAttribute);
System.out.println("outerStaticVariable:" + outerStaticAttribute);
outerMethod();
outerMethodStatic();
}
}
Inner inner = new Inner();
inner.innerShow();
}
}
输出结果:
外部类的静态代码块执行了。。。。。。。。。
innerAttribute: 10
是否男性: false
参数value: 1000
outerAttribute:1
内部的commonVariable:20
外部的commonVariable:2
outerStaticVariable:3
外部类普通方法,outerMethod===========================
外部类静态方法,outerMethodStatic====================
总结:
- 仅在此方法内使用。可以随意的访问外部类的任何信息。内部类和外部类的同名属性不会覆盖
修改如下图:
已被赋值且始终未改变的变量(有且仅有赋值一次),引用指向不能改变
(3)匿名内部类
因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写
但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口
1:不适用内部类实现
package ***********.test.inner;
public class Anonymous {
public static void main(String[] args) {
Person p = new Child();
p.eat();
}
}
abstract class Person{
public abstract void eat();
}
class Child extends Person{
@Override
public void eat() {
System.out.println("eat something");
}
}
2:方式一,使用抽象类
package ************.test.inner;
public class AnonymousAbstract {
public static void main(String[] args) {
Person1 p = new Person1() {
@Override
public void eat() {
System.out.println("eat =======================");
}
};
p.eat();
}
}
abstract class Person1{
public abstract void eat();
}
3:方式二:使用接口实现
interface Person {
public void eat();
}
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println("eat something");
}
};
p.eat();
}
}
由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现



