《java核心技术卷Ⅰ》第六章:接口、lambda表达式与内部类

第六章:接口、lambda表达式与内部类

到目前为止,读者已经学习了 Java 面向对象程序设计的全部基本知识。本章将开始介 绍几种常用的高级技术。这些内容可能不太容易理解,但一定要掌握它们,以便完善自己的 Java 工具箱。 首先,介绍一下接口( interface) 技术, 这种技术主要用来描述类具有什么功能,而并不 给出每个功能的具体实现。一个类可以实现( implement) —个或多个接口,并在需要接口的地方, 随时使用实现了相应接口的对象。 了解接口以后,再继续介绍lambda表达式,这是一种表示可以在将来某个时间点执行的代码块的简洁方法。使用 lambda 表达式,可以用一 种精巧而简洁的方式表示使用回调或变量行为的代码。 接下来,讨论内部类( inner class) 机制。理论上讲,内部类有些复杂, 内部类定义在另 外一个类的内部, 其中的方法可以访问包含它们的外部类的域。内部类技术主要用于设计具有相互协作关系的类集合。 在本章的最后还将介绍代理(proxy), 这是一种实现任意接口的对象。代理是一种非常 专业的构造工具,它可以用来构建系统级的工具。如果是第一次学习这本书,可以先跳过这个部分。


知识点整理(不包含代理那节)


接口

EmployeeSortTest.java

package interfaces;
import java.util.Arrays;
public class EmployeeSortTest {
       public static void main(String[] args) {
             Employee[] staff = new Employee[3];

             staff[0] = new Employee("Harry Hacker", 35000);
             staff[1] = new Employee("Carl Cracker", 75000);
             staff[2] = new Employee("Tony Tester", 38000);

             Arrays.sort(staff);

             //print out information about all Employee objects
             for(Employee e : staff)
                    System.out.println("name=" + e.getName() + ",salary=" +  e.getSalary());
       }
}

Employee.java

package interfaces;
public class Employee implements Comparable<Employee>{
       private String name;
       private double salary;

       public Employee(String name, double salary) {
             this.name = name;
             this.salary = salary;
       }

       public String getName() {
             return name;
       }

       public double getSalary() {
             return salary;
       }

       public void raiseSalary(double byPercent) {
             double raise = salary * byPercent / 100;
             salary += raise;
       }

       /*
        * Compares employees by salary
        * @param other another Employee object
        * @return  a negative value if this employee has lower salary than  otherObject,
        * o if the salaries are the same, a positive value otherwise
        */
       public int compareTo(Employee other) {
             return Double.compare(salary, other.salary);
       }
}

接口示例

接口与回调

TimerTest.java

package timer;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
//to resolve conflict with java.util.Timer
public class TimerTest {
       public static void main(String[] args) {
             ActionListener listener = new TimePrinter();

             //construct a timer that calls the listener
             //once every 10 seconds
             Timer t = new Timer(5000, listener);
             t.start();
             JOptionPane.showMessageDialog(null, "Quit program?");
             System.exit(0);
       }
}
class TimePrinter implements ActionListener{
       public void actionPerformed(ActionEvent event) {
             System.out.println("At the tone, the tiome is " + new Date());
             Toolkit.getDefaultToolkit().beep();
       }
}

对象克隆

CloneTest.java

package clone;
public class CloneTest {
       public static void main(String[] args) {
             try {
                    Employee original = new Employee("John Q. Public", 50000);
                    original.setHireDay(2000, 1, 1);
                    Employee copy = original.clone();
                    copy.raiseSalary(10);
                    copy.setHireDay(2002, 12, 31);
                    System.out.println("original=" + original);
                    System.out.println("copy=" + copy);
             } catch(CloneNotSupportedException e) {
                    e.printStackTrace();
             }
       }
}

Employee.java

package clone;
import java.util.Date;
import java.util.GregorianCalendar;
public class Employee implements Cloneable{
       private String name;
       private double salary;
       private Date hireDay;

       public Employee(String name, double salary) {
             this.name = name;
             this.salary = salary;
             hireDay = new Date();
       }

       public Employee clone() throws CloneNotSupportedException
       {
             //call Object.clone()
             Employee cloned = (Employee) super.clone();

             //clone mutable fields
             cloned.hireDay = (Date)hireDay.clone();

             return cloned;
       }

       /*
        * Set the hire day to a given date.
        * @param year the year of the hire day
        * @param month the month of the hire day
        * @param day the day of the hire day
        */
       public void setHireDay(int year, int month, int day) {
             Date newHireDay = new GregorianCalendar(year, month - 1,  day).getTime();

             //Example of instance field mutation
             hireDay.setTime(newHireDay.getTime());
       }

       public void raiseSalary(double byPercent) {
             double raise = salary * byPercent / 100;
             salary += raise;
       }

       public String toString() {
             return ("Employee[name=" + name +",salary=" + salary + ",hireDay="  + hireDay + "]");
       }
}

lambda表达式

lambda表达式的语法

LambdaTest.java

package lambda;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class LambdaTest {
       public static void main(String[] args) {
             String[] planets = new String[] { "Mercury", "Venus", "Earth",  "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"};
             System.out.println(Arrays.toString(planets));
             System.out.println("Sorted in dictionary order:");
             Arrays.sort(planets);
             System.out.println(Arrays.toString(planets));
             System.out.println("Sorted by length:");
             Arrays.sort(planets, (first, second) -> first.length() -  second.length());
             System.out.println(Arrays.toString(planets));

             Timer t = new Timer(1000, event -> System.out.println("The time is  " + new Date()));
             t.start();

             //keep program running until user selects "Ok"
             JOptionPane.showMessageDialog(null, "Quit program?");
             System.exit(0);
       }
}

内部类

使用内部类访问对象状态

InnerClassTest.java

package innerClass;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class InnerClassTest {
       public static void main(String[] args) {
             TalkingClock clock = new TalkingClock(1000, true);
             clock.start();

             // kepp program running until user selects "Ok"
             JOptionPane.showMessageDialog(null, "Quit program?");
             System.exit(0);
       }
}
/*
* A clock that prints the time in regular intervals
*/
class TalkingClock{
       private int interval;
       private boolean beep;

       /*
        * Constructs a talking clock
        * @param interval the interval between messages(in milliseconds)
        * @param beep true if the clock should beep
        */
       public TalkingClock(int interval, boolean beep)
       {
             this.interval = interval;
             this.beep = beep;
       }

       /*
        * Starts the clock
        */
       public void start() {
             ActionListener listener = new TimePrinter();
             Timer t = new Timer(interval, listener);
             t.start();
       }

       public class TimePrinter implements ActionListener{
             public void actionPerformed(ActionEvent event) {
                    System.out.println("At the tone, the time is " + new  Date());
                    if(beep) Toolkit.getDefaultToolkit().beep();
             }
       }
}

匿名内部类

AnonymousInnerClassTest

package anonymousInnerClass;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class AnonymousInnerClassTest {
    public static void main(String[] args) {
        TalkingClock clock = new TalkingClock();
        clock.start(1000, true);

        // keep program running until user selects "Ok"
        JOptionPane.showMessageDialog(null, "Quit program?");
        System.exit(0);
    }
}

/*
 * A clock that prints the time in regular intervals
 */
class TalkingClock{
    /*
     * Starts the clock.
     * @param interval the interval between messages(in molliseconds)
     * @param beep true if the clock should beep
     */
    public void start(int interval, boolean beep) {
        ActionListener listener = new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                System.out.println("At the tone, the time is " + new Date());
                if(beep) Toolkit.getDefaultToolkit().beep();
            }
        };
        Timer t = new Timer(interval, listener);
        t.start();
    }
}

静态内部类

StaticInnerClassTest

package staticInnerClass;

public class StaticInnerClassTest {
    public static void main(String[] args) {
        double[] d = new double[20];
        for(int i = 0; i < d.length; i++) {
            d[i] = 100 * Math.random();
        }
        ArrayAlg.Pair p = ArrayAlg.minmax(d);
        System.out.println("min = " + p.getFirst());
        System.out.println("max = " + p.getSecond());
    }
}

class ArrayAlg{
    /**
     * A pair of floating-point numbers
     */
    public static class Pair{
        private double first;
        private double second;

        /**
         * Constructs a pair from two floating-point numbers
         * @param f the first number
         * @param s the second number
         */
        public Pair(double f, double s) {
            first = f;
            second = s;
        }

        /**
         * Returns the first number of the pair
         * @return the first number
         */
        public double getFirst() {
            return first;
        }

        /**
         * Return the second number of the pair
         * @return the second number
         */
        public double getSecond() {
            return second;
        }
    }

    /**
     * Computes both the minimum and the maximum of an array
     * @param values an array of floating-point numbers
     * @return a pair whose first element is the minimum and whose second element is the maximum 
     */
     public static Pair minmax(double[] values) {
         double min = Double.POSITIVE_INFINITY;
         double max = Double.NEGATIVE_INFINITY;
         for(double v : values) {
             if(min > v) min = v;
             if(max < v) max = v;
         }
         return new Pair(min, max);
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值