疯狂java笔记——内部类

1.非静态内部类

2.静态内部类(static修饰)

 

内部类可以比外部类多三个修饰符:private,protected,static——外部类不可以使用这三个修饰符。

 

 

非静态内部类是可以访问 外部类成员变量的,因为在编译时,非静态内部类要访问某个变量,系统优先在方法内查找,找不到就去该方法所在内部类找,还找不到就去外部类找,知道在外部类找到了,如果该变量不存在就会编译错误。

 

如果外部类和内部类有成员变量同名

可以用this, 如 外部类Name.this.变量名

内部类的变量: this.变量名

 

非静态的内部类可以访问外部类private成员,但是反过来不成立,就是外部类不能访问内部类成员

如果外部类想要访问非静态内类成员,必须显式创建非静态内部类对象来调用其成员。

 

如下;

public class Outer

{

private int outProp = 9;

class Inner

{

private int inProp = 5;

public void acessOuterProp()

{

// 非静态内部类可以直接访问外部类的private成员变量

System.out.println(“外部类的outProp值:”+ outProp);

}

}

public void accessInnerProp()

{

// 外部类不能直接访问非静态内部类的实例变量,

// 下面代码出现编译错误

// System.out.println(“内部类的inProp值:” + inProp);

// 如需访问内部类的实例变量,必须显式创建内部类对象

System.out.println(“内部类的inProp值:”+ new Inner().inProp);

}

public static void main(String[] args)

{

// 执行下面代码,只创建了外部类对象,还未创建内部类对象

Outer out = new Outer(); //①

out.accessInnerProp();

}

}

 

同样,外部类的静态方法不能访问非静态内部类(所有静态都不能访问非静态呀)

如下:

public class StaticTest

{

// 定义一个非静态的内部类,是一个空类

private class In{}

// 外部类的静态方法

public static void main(String[] args)

{

// 下面代码引发编译异常,因为静态成员(main()方法)

// 无法访问非静态成员(In类)

new In();

}

}

 

 

java不容许 非静态内部类里定义静态成员,(非静态类里面不容许有静态声明)如下:

public class InnerNoStatic

{

private class InnerClass

{

/*

下面三个静态声明都将引发如下编译错误:

非静态内部类不能有静态声明

*/

static

{

System.out.println(“==========”);

}

private static int inProp;

private static void test(){}

}

}

 

 

 

静态内部类:static修饰的内部方法

static修饰的方法属于外部类本身,而不属于外部类的某个对象。

 

静态内部类不能访问外部实例变量,只能访问静态成员变量(static修饰的成员变量,也成类变量)。

public class StaticInnerClassTest

{

private int prop1 = 5;

private static int prop2 = 9;

 

//静态内部类

static class StaticInnerClass

{

// 静态内部类里可以包含静态成员

private static int age;

public void accessOuterProp()

{

// 下面代码出现错误:

// 静态内部类无法访问外部类的实例变量

System.out.println(prop1);

// 下面代码正常

System.out.println(prop2);

}

}

}

 

 

外部类依旧不能直接访问静态内部类的成员,但可以向上面一样调度,如下:

 

public class AccessStaticInnerClass

{

static class StaticInnerClass

{

private static int prop1 = 5; //类成员

private int prop2 = 9; //实例成员

}

 

public void accessInnerProp()

{

// System.out.println(prop1);

// 上面代码出现错误,应改为如下形式:

 

// 通过类名访问静态内部类的类成员

System.out.println(StaticInnerClass.prop1);

 

// System.out.println(prop2);

// 上面代码出现错误,应改为如下形式:

 

// 通过实例访问静态内部类的实例成员

System.out.println(new StaticInnerClass().prop2);

}

}

 

内部类的使用:

 

在外部类以外的地方创建非静态内部类实例必须使用外部类实例和new来调用非静态内部类的构造器。如下

 

//out外部类

class Out

{

//非静态内部类

class In

{

//in方法

public In(String msg)

{

System.out.println(msg);

}

}

}

 

public class CreateInnerInstance

{

public static void main(String[] args)

{

Out.In a = new Out().new In(“测试信息”); //前面in是类名,后面in是构造器

/*

上面代码可改为如下三行代码:

使用OutterClass.InnerClass的形式定义内部类变量

Out.In a;

创建外部类实例,非静态内部类实例将寄存在该实例中

Out b = new Out();

通过外部类实例和new来调用内部类构造器创建非静态内部类实例

a = b.new In(“测试信息”);

*/

}

}

非静态内部类的构造器必须通过外部类对象调用

 

 

子类继承内部类:

public class SubClass extends Out.In

{

//显示定义SubClass的构造器

public SubClass(Out out)

{

//通过传入的Out对象显式调用In的构造器

out.super(“hello”);

}

}

如上表示:SubClass继承了OUT类的内部类in类。

通过外部类对象out, super表示调用In类的构造器,

 

 

局部内部类:

在方法内定义内部类,就是局部内部类,局部内部类不能再外部类以外的地方使用,因此局部内部类不能用访问控制符和static修饰。

如下:

public class LocalInnerClass

{

public static void main(String[] args)

{

// 定义局部内部类

class InnerBase

{

int a;

}

// 定义局部内部类的子类

class InnerSub extends InnerBase

{

int b;

}

// 创建局部内部类的对象

InnerSub is = new InnerSub();

is.a = 5;

is.b = 8;

System.out.println(“InnerSub对象的a和b实例变量是:”

+ is.a + “,” + is.b);

}

}

java8中改进的匿名类

interface Product

{

public double getPrice();

public String getName();

}

public class AnonymousTest

{

public void test(Product p)

{

System.out.println(“购买了一个” + p.getName()

+ “,花掉了” + p.getPrice());

}

public static void main(String[] args)

{

AnonymousTest ta = new AnonymousTest();

// 调用test()方法时,需要传入一个Product参数,

// 此处传入其匿名实现类的实例

ta.test(new Product()

{

public double getPrice()

{

return 567.8;

}

public String getName()

{

return “AGP显卡”;

}

});

}

}

 

 

还有:

abstract class Device

{

private String name;

public abstract double getPrice();

public Device(){}

public Device(String name)

{

this.name = name;

}

// 此处省略了name的setter和getter方法

public void setName(String name)

{

this.name = name;

}

public String getName()

{

return this.name;

}

}

public class AnonymousInner

{

public void test(Device d)

{

System.out.println(“购买了一个” + d.getName()

+ “,花掉了” + d.getPrice());

}

public static void main(String[] args)

{

AnonymousInner ai = new AnonymousInner();

// 调用有参数的构造器创建Device匿名实现类的对象

ai.test(new Device(“电子示波器”)

{

public double getPrice()

{

return 67.8;

}

});

 

 

// 调用无参数的构造器创建Device匿名实现类的对象

Device d = new Device()

{

// 初始化块

{

System.out.println(“匿名内部类的初始化块…”);

}

// 实现抽象方法

public double getPrice()

{

return 56.2;

}

// 重写父类的实例方法

public String getName()

{

return “键盘”;

}

};

ai.test(d);

}

}

 

    原文作者:IMAlex233
    原文地址: https://blog.csdn.net/qq_36332133/article/details/81182755
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞