内部类
定义:将一个类定义在另一个类的里面,对李米娜那个类就称为内部类(内置类,嵌套类)。
访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。
外部类要访问内部类中的成员必须要建立内部类的对象。
例子:
class Outer{
private int num = 3;
class Inner//内部类;
{
void show(){
System.out.println("show Inner run...");
}
}
publi void method(){
Inner in = new Inner();
in.show();
}
}
class InnerClassDemo{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
}
}
注意:
内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两个类。对于一个名为Outer的外部类和其中内部定义的名为Inner的内部类。
编译完成后会出现Outer.class和Outer$Inner.class两个字节码文件。所以内部类的成员变量和方法名可以和外部类的相同。
内部类在编译的时候,也会编译成一个.class文件。文件名称:外部类$内部类.class 形式。
内部类的意义:
为了访问属性方便。
应用场景:
一般用于类的设计。分析事物的时候,发现对该事物的描述中还有事物,而且这个事物
还在访问被描述事物的内容。这时就把这些事物定义成内部类来描述。
成员内部类:
成员内部类,就是作为外部类中的成员,可以直接使用外部类的所有成员和方法,即使是私有成员。同时外部类要访问内部类的所有成员
变量和方法,则需要通过内部类的对象来获取。
注意:成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建内部类。
内部类的特点:
可以被成员修饰符修饰;
直接访问外部类中的内部类中的成员。
例子:
class Outer{
private int num = 3;
class Inner//内部类;
{
void show(){
System.out.println("show Inner run...");
}
}
publi void method(){
Inner in = new Inner();
in.show();
}
}
class InnerClassDemo{
public static void main(String[] args)
{
//常见格式。
//直接访问外部类中的内部类中的成员。
Outer.Inner in = new Outer().new Inner();
//注:这种格式不常见。内部类一般都被封装了;私有的就不能被访问了;
in.show();
//当内部类使用static修饰的时候,访问内部类。
//如果内部类是静态的额,相当是一个外部类。
//访问时,直接new一个内部类对象:
Outer.Inner in = new Outer.Inner();
in.show();
//如果内部类是静态的,成员是静态的。
//不需要new 对象。
Outer.Inner.function();
}
//注意:如果内部类中定义了静态成员,该内部类也必须是静态的。
}
内部类的细节:
为什么内部类能直接访问外部类中的成员呢?
那是因为内部类持有了外部类的引用:外部类名.this;
class Outer{
int num = 3;
class Inner{
int num = 4;
void show(){
int num = 5;
System.out.println(num);
}
}
void method(){
new Inner().show();
}
}
class InnerClasssDemo2{
public static void main(String[] args){
System.out.println("Hello World");
new Outer().method();//输出:5;
打印4:
改method中System.out.println(this.num);
打印3:
改method中System.out.println(Outer.this.num);
}
}
局部内部类:
内部类可以存放在局部位置上;
原因:
内部类在局部位置上只能访问局部中被final修饰的局部变量。
class Outer{
int num = 3;
void method(){
final int x = 9;//从内部类中访问局部变量,变量必须是最终类型。
class Inner{
void method(){
System.out.println("Inner ...show..."+x);
}
}
Inner in = new Inner();
in.show();
}
}
class InnerClassDemo3{
public static void main(String[] args){
System.out.println("Hello World!");
}
}
匿名内部类:就是内部类的简写格式。
前提:
内部类必须继承或者实现一个外部类或者接口。
匿名内部类:
其实就是一个匿名子类对象。
简化封装动作。
格式: new 父类or接口名(){内容}
abstract class Demo
{
abstract void show();
}
class Outer {
int num = 4;
/*
class Inner extends Demo
{
void show(){
System.out.println("show...+"num);
}
}*/
public void method(){
//new Inner().show();
new Demo()//new了一个Demo的子类;是匿名内部类。
{
void show()
{
System.out.println("show ........"+num);
}
}.show();//调用show()方法。
}
}
class InnerClassDemo4{
public static void main(String[] args){
System.out.println("Hello World");
}
}
匿名内部类的应用:
interface Inter
{
void show1();
void show2();
}
class Outer
{
/*class Inner implements Inter
{
public void show1()
{
}
public void show2()
{
}
}*/
/*
通常使用的场景之一:
当函数参数是接口类型时,而且接口中的方法不超过三个。
可以用匿名内部类作为实际参数进行传递。
*/
public void method(){
Inter in = new Inter(){
public void show1(){
}
public void show2(){
}
};
}
//此时,如何调用show2方法?
可以,定义对象;
in.show1();
in.show2();
}
InnerClassDemo5
{
public static void main(String[] args)
{
System.out.println("Hello World");
}
}
匿名内部类的细节:
class Outer
{
void method()
{
Object obj = new Object()
{
public void show()
{
System.out.println("show run");
}
};
obj.show();//因为匿名内部类这个子类对象呗向上转型为了Object类型。
//这样就不能再使用子类特有的方法了。
}
}
class InnerClassDemo6
{
publiv static void main(String[] args)
{
System.out.println("hello world....");
}
}