使用内部类和闭包

内部类

  在Java中创建类时,也就定义了类的属性和行为。属性是用来存放数据的类和实例变量,行为是使用存放的数据来执行任务的方法。

  类中还可以包含由属性和行为组成的其他东西:内部类。

  内部类是包含在一个封闭类中的辅助类。

  在Java中包含内部类的原因有3个。

  1.当辅助类只能被另外一个类使用时,就可以在那个类中定义辅助类。

  2.这可以使得辅助类能够访问private 方法和变量;而这些方法和变量是不能被单独的类所访问的。

  3.当在另一个类中使用辅助类时,可以让辅助类距离类足够近。

  与其他类一样,可以使用class关键字来创建内部类,但是它是在所属类的内部声明的。通常类的内部是放置类和实例变量的地方。

  内部类的结构与其他类一样,但是位置是在封闭类的“{” 和“}”内部。创建内部类需要外部类的对象,然后这个外部类对象调用new操作符。

 1 import java.net.*;
 2 
 3 public class Catalog {
 4     class HomePage {
 5         String owner;
 6         URL address;
 7         String category = "none";
 8         
 9         public HomePage(String inOwner, String inAddress)
10             throws MalformedURLException {
11             owner = inOwner;
12             address = new URL(inAddress);
13         }
14         
15         public HomePage(String inOwner, String inAddress, String inCategory) 
16             throws MalformedURLException {
17                 this(inOwner, inAddress);
18                 category = inCategory;
19         }
20         
21     }
22     public Catalog() {
23         Catalog.HomePage[] catalog = new Catalog.HomePage[5];
24         try {
25             catalog[0] = new HomePage("Mark Evanier",
26                     "http://www.newsfromme.com", "commic books");
27             catalog[1] = new HomePage("Jeff Rients",
28                     "http://jrients.blogspot.com", "gaming");
29             catalog[2] = new HomePage("Rogers Cadenhead",
30                     "http://workbench.cadenhead.org", "programming");
31             catalog[3] = new HomePage("Juan Cole", 
32                     "http://www.juancole.com", "politics");
33             catalog[4] = new HomePage("Rafe Colburn",
34                     "http://www.rc3.org");
35             for (int i = 0; i < catalog.length; i++) {
36                 System.out.println(catalog[i].owner + ": " + 
37                         catalog[i].address + " -- " + 
38                         catalog[i].category);
39             }
40         } catch (MalformedURLException e) {
41             System.out.println("Error: " + e.getMessage());
42         }
43     }
44     
45     public static void main(String[] arguments) {
46         new Catalog();
47     }
48 }
内部类示例

匿名内部类

 在Java编程中经常执行的一个任务是创建一个只使用一次使用一次且用途简单的类。一种特殊的内部类可以完美地实现该目的。

  匿名内部类是没有名字,而且声明与创建是在同时进行的类。

 要使用匿名内部类,要使用new关键字以及“{”和“}”内部的类定义来替换对对象的引用,其中new关键字会调用构造函数。

 匿名内部类可以执行正常助手做不到的事情:该问keyLabel实例变量。该变量属于KeyViewer类。内部类可以访问所属类的方法和变量。

  匿名内部类不能定义构告函数,因此相较于非匿名的内部类,其限制更多。

  匿名内部类是Java语言中的一个复杂特性,在查看程序的源代码时会很难理解,但是它可以让程序更为简洁,有经验的Java程序员会经常使用匿名内部类。

 1 import javax.swing.*;
 2 import java.awt.event.*;
 3 import java.awt.*;
 4 
 5 public class NewKeyViewer extends JFrame {
 6     JTextField keyText = new JTextField(80);
 7     JLabel keyLabel = new JLabel("Press any key in the text field.");
 8     
 9     public NewKeyViewer() {
10         super("NewKeyViewer");
11         setLookAndFeel();
12         setSize(350, 100);
13         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
14         keyText.addKeyListener(new KeyAdapter() {
15             public void keyTyped(KeyEvent input) {
16                 char key = input.getKeyChar();
17                 keyLabel.setText("You pressed " + key);
18             }
19         });
20         
21         BorderLayout bord = new BorderLayout();
22         setLayout(bord);
23         add(keyLabel, BorderLayout.NORTH);
24         add(keyText, BorderLayout.CENTER);
25         setVisible(true);
26     }
27     private void setLookAndFeel() {
28         try {
29             UIManager.setLookAndFeel(
30                     "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
31         } catch (Exception exc) {
32             
33         }
34     }
35     
36     public static void main(String[] arguments) {
37         new NewKeyViewer();
38     }
39 }
View Code

闭包

  闭包也称为lambda表达式,在其他条件满足的情况下,它是可以只使用一个 -> 操作符创建带有单个参数的对象。

  Runnable runner = () - > {System.out.println("Run!");};

 1 import java.awt.*;
 2 import java.awt.event.*;
 3 import javax.swing.*;
 4 
 5 public class NewColorFrame extends JFrame {
 6     JButton red, green, blue;
 7     
 8     public NewColorFrame() {
 9         super("NewColorFrame");
10         setLookAndFeel();
11         setSize(322, 122);
12         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
13         FlowLayout flo = new FlowLayout();
14         setLayout(flo);
15         red = new JButton("Red");
16         add(red);
17         green = new JButton("Green");
18         add(green);
19         blue = new JButton("Blue");
20         add(blue);
21         //begin lambda expression
22         ActionListener act = (event) -> {
23                 if (event.getSource() == red) {
24                     getContentPane().setBackground(Color.RED);
25                 }
26                 if (event.getSource() == green) {
27                     getContentPane().setBackground(Color.GREEN);
28                 }
29                 if (event.getSource() == blue) {
30                     getContentPane().setBackground(Color.BLUE);
31                 }
32         };
33         //end lambda expression
34         red.addActionListener(act);
35         green.addActionListener(act);
36         blue.addActionListener(act);
37         setVisible(true);
38     }
39     
40     private void setLookAndFeel() {
41         try {
42             UIManager.setLookAndFeel(
43                     "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
44         } catch (Exception e) {
45             //ignore error
46         }
47     }
48     
49     public static void main(String[] arguments) {
50         new NewColorFrame();
51     }
52 }
View Code

  lambda表达式支持函数式编程。函数式编程是软件设计中的一种方法,直到现在才开始被Java程序员使用。

  lambda表达式的一个效果是缩短了代码。一个表达式就可以创建一个对象并实现一个接口。这一新特性可以让代码更简洁

原文地址:https://www.cnblogs.com/dulixiaoqiao/p/6528668.html