学习笔记之JavaSE(19)--面向对象编程10

来源:互联网 发布:java 视频播放控件 编辑:程序博客网 时间:2024/06/05 06:43

今天学习的内容是内部类


内部类就是将一个类的定义放在另一个类的内部。内部类的知识点如下:

  • 内部类分为成员内部类、局部内部类和匿名内部类
  • 编译期过后,每个内部类都会生成一个字节码文件
  • 成员内部类:外部类名$内部类名.class
  • 局部内部类:外部类名$数字标识+内部类名.class
  • 匿名内部类:外部类名$数字标识.class
  • 外部类的非静态方法中创建内部类对象的格式:内部类 引用=new 内部类();
  • 别的类或者外部类的静态方法中必须借助外部类对象来创建内部类对象,格式:外部类.内部类 引用=外部类引用.new 内部类()
  • 内部类可以直接访问外部类的内容,包括private内容。原因是内部类持有外部类.this,也就是说编译器帮着自动添加了外部类.this
  • 外部类不能直接访问内部类的内容,必须先创建内部类对象。注意在外部类中也可以访问内部类的private内容
  • 成员内部类还可以是private、protected和static的
  • private内部类只能在外部类访问,所以使用private内部类有点类似使用private构造方法。一般先让private内部类实现某个接口,然后设置一个getter方法用来获得内部类对象(方法返回值为接口)。通过此方法获得内部类对象之后再向上转型为接口类型即可。protected内部类与之类似,只是访问权限有些不同。这就是内部类最基本用途!!
  • 创建静态内部类对象不需要借助外部类对象;如果内部类中定义了静态内容,该内部类必须是静态内部类
  • 在定义局部内部类的方法的外部不能访问该内部类,但是该内部类可以访问该方法的局部变量以及外部类的所有成员,注意局部内部类只能访问final局部变量
  • 使用匿名内部类的前提:匿名内部类必须继承或实现某外部类或接口
  • 匿名内部类实质上就是向上转型
  • 不要在匿名内部类中定义接口没有的方法,因为即使你定义了,接口引用也不能调用(但是匿名内部类对象本身可以调用)
  • 匿名内部类既可以扩展类,也可以实现接口,但不能两者兼备。而且如果实现接口,也只能实现一个接口。(要不实现一个接口,要不就继承一个类)
  • 匿名内部类的使用场景通常是:当方法参数是接口类型,且接口中的方法不超过三个,可以使用匿名内部类作为实参进行传递(swing中监听经常使用匿名内部类)
  • 使用局部内部类而不是匿名内部类的理由有两个:第一,我们需要一个已命名的构造函数。第二,需要不止一个该内部类对象
示例程序:
interface A{}public class Outer {private int a=1;private Inner_1 in;//成员内部类,可以声明为private和protected和staticclass Inner_1{//字节码文件名Outer$Inner_1.class private int b=1;public void go(){System.out.println("外部类中的a="+a);//内部类可以直接访问外部类的内容,包括private内容//原因:内部类持有外部类的this,编译器帮着自动添加了外部类.this,也就是Outer.this}}//private内部类一般实现某个接口(protected)private class Inner_3 implements A{}//字节码文件名Outer$Inner_3.class//静态内部类static class Inner_4{//字节码文件名Outer$Inner_4.class static int A=0;}public void show(){//!System.out.println(b); 外部类不能直接访问内部类的内容//外部类要访问内部类的内容,必须创建内部类对象in=new Inner_1();//在外部类的非静态方法中创建内部类对象in.go();System.out.println("内部类中的b="+in.b);//注意:外部类中也可以访问内部类的private成员}public static void shouInStatic(){//外部类要访问内部类的内容,必须创建内部类对象Outer out=new Outer();Outer.Inner_1 in=out.new Inner_1();//在外部类的静态方法中创建内部类对象in.go();System.out.println("内部类中的b="+in.b);//注意:外部类中也可以访问内部类的private成员}//设置一个getter方法用来获得内部类对象public A getInner_3(){return new Inner_3();}//定义局部内部类的方法public void method(final int z){@SuppressWarnings("unused")int x=10;final int y=10;//局部内部类class Inner_2{//字节码文件名Outer$1Inner_2.class public void go(){System.out.println("外部类中的a="+Outer.this.a);//局部内部类也可以访问外部类成员//!System.out.println(x);  局部内部类只能访问方法的final局部变量System.out.println(y);System.out.println(z);}}Inner_2 in=new Inner_2();in.go();}}class OuterTest{public static void main(String[] args){Outer out=new Outer();out.show();//别的类要访问内部类的内容,必须借助外部类创建内部类对象Outer.Inner_1 in=out.new Inner_1();//在别的类创建内部类对象in.go();//!System.out.println("内部类中的b="+in.b);//注意:在别的类不能访问内部类的private成员A a=out.getInner_3();//将private内部类向上转型为接口类型//!Outer.Inner_3 in=out.new Inner_3();  private内部类不能使用这种方式创建out.method(1);//}}
public class Frame {private JFrame frame;private JButton button;public void gui(){frame=new JFrame();button=new JButton("button");frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.getContentPane().add(button);showClick();}public void showClick(){//匿名内部类//前提:匿名内部类必须继承或实现某外部类或接口,在这里就是实现了ActionListener接口//格式:new 父类/接口(){子类/实现类内容}//通常使用场景:当方法参数是接口类型,且接口中的方法不超过三个,可以使用匿名内部类作为实参进行传递button.addActionListener(new ActionListener() {//字节码文件名Outer$1.class @Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubbutton.setText("I'm clicked!");}});//注意:实际上这是向上转型}public static  void main(String[] args){new Frame().gui();}}



0 0