您的位置:首页 > 编程语言 > Java开发

《Java核心技术》复习笔记 - 第六章 接口与内部类

2014-03-03 20:20 387 查看
《Java核心技术》复习笔记 - 第六章 接口与内部类

1. 接口和抽象类的区别

2. Java不支持多重继承,但是引入了接口的概念,声明一个接口用关键字interface,实现接口用关键字implements,接口是可以继承的。接口绝不能含有实例域,也不能在接口中实现方法。接口中的所有方法自动为public,在实现接口时,必须把实现的方法声明为public,否则编译器认为该方法是包可见性,并可出一个警告。接口中可以包含常量,接口中的域被自动设为public static final。

3. Object有一个protected的clone方法,提供的克隆操作为浅拷贝,即没有拷贝对象所引用的对象。如果原始对象与浅拷贝对象共享的子对象是不可变的,将不会产生任何问题。但是更常见的是子对象是可变的,这时就要重新定义clone方法,以便提供深拷贝语义。由于Object提供的clone方法为protected,因此子类只能调用受保护的clone方法克隆它自己。为此,必须重新定义clone方法,并将他申明为public,这样才能让所有的方法克隆该类的对象。





import java.util.*;

/**
* This program demonstrates cloning.
* @version 1.10 2002-07-01
* @author Cay Horstmann
*/
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();
}
}
}

class Employee implements Cloneable
{
public Employee(String n, double s)
{
name = n;
salary = s;
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 + "]";
}

private String name;
private double salary;
private Date hireDay;
}


4. 所有数组类型都包含一个clone方法,这个方法被设为public,而不是protected,可以利用这个方法创建一个包含所有数据元素拷贝的新数组。

5. 内部类既可以访问自身的数据域,也可以访问创建它的外围类对象的数据域。内部类对象有一个隐式引用,指向创建它的外部类对象。外围类的引用是在构造器中设置的,编译器会修改所有内部类的构造器,添加一个外围类的引用参数。

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

/**
* This program demonstrates the use of inner classes.
* @version 1.10 2004-02-27
* @author Cay Horstmann
*/
public class InnerClassTest
{
public static void main(String[] args)
{
TalkingClock clock = new TalkingClock(1000, true);
clock.start();

// 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
{
/**
* 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();
}

private int interval;
private boolean beep;

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


6. 只有内部类可以是私有的,而常规类只可以具有包可见性或公有可见性。

7. 局部内部类:如果内部类只在某个方法中使用了一次,就可以在方法中定义一个局部内部类。局部内部类不能用public或private访问说明符进行申明。它的作用域被限定在申明这个局部类的块中。局部类不仅可以访问外部类,还可以访问局部变量,不过这些局部变量必须被申明为final。

8. 匿名内部类:如果只创建局部内部类的一 个对象,就不用命名了。这种类被称为匿名内部类,如GUI编程中的监听器类对象。

9. 静态内部类:有时候使用内部类只是为了把一个类隐藏在另一个类的内部,并不需要内部类引用外部类的对象,为此,可以将内部类申明为static,以便取消产生的引用。只有内部类可以声明为static,声明在接口中的内部类自动成为static和public。

/**
* This program demonstrates the use of static inner classes.
* @version 1.01 2004-02-27
* @author Cay Horstmann
*/
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
{
/**
* 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;
}

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

private double first;
private double 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.MAX_VALUE;
double max = Double.MIN_VALUE;
for (double v : values)
{
if (min > v) min = v;
if (max < v) max = v;
}
return new Pair(min, max);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: