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

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

1. 接口和抽象类的区别

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

3. Object有一个protectedclone方法,提供的克隆操作为浅拷贝,即没有拷贝对象所引用的对象。如果原始对象与浅拷贝对象共享的子对象是不可变的,将不会产生任何问题。但是更常见的是子对象是可变的,这时就要重新定义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. 局部内部类:如果内部类只在某个方法中使用了一次,就可以在方法中定义一个局部内部类。局部内部类不能用publicprivate访问说明符进行申明。它的作用域被限定在申明这个局部类的块中。局部类不仅可以访问外部类,还可以访问局部变量,不过这些局部变量必须被申明为final

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

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

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值