java之內部類

內部類就是定義在另一個類中的類,使用內部類的理由主要有以下三點:

1)內部類方法可以訪問該類定義在作用域中的數據,包括私有數據。

2)內部類可以對同一個包中的其他類隱藏起來。

3)當想要定義一個回調函數且不想編寫大量代碼時,使用匿名內部類比較便捷。

內部類根據定義的位置不同,可以分爲四種,第一種就是普通的內部類,第二種是局部內部類,第三種是匿名內部類,第四種是靜態內部類。


這裏只需強調一點即可,就是爲了運行使用了其外部實例域的內部類,內部類對象中總有一個隱式引用,它指向了創建它的外部類對象,因此其內部類可以使用其外部類的實例域。

當然,既然有隱式引用,當然可以顯式的表達出來了。

對於內部類引用外部類中數據,可以使用以下語法:外部類名.this.數據名

例如下面例子中的:

if(beep)可以顯式的寫爲if(TalkingClock.this.beep)

創建一個內部類對象的時候也可以顯式的說明,可以使用以下語法:內部類名 對象名=this.new 內部類名(參數);

例如下面例子中的:

ActionListener listener=new TimePrinter();可以顯式的寫爲ActionListener listener=this.new TimePrinter();

下面是一個完整的例子:

代碼:

package InnerClasses;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class InnerClassTest {
	public static void main(String[] args) {
		TalkingClock clock = new TalkingClock(1000,true);
		clock.start();
		
		JOptionPane.showMessageDialog(null,"關閉??");
		System.exit(0);
	}
}

class TalkingClock{
	private int interval;
	private boolean beep;
	
	public TalkingClock(int interval,boolean beep) {
		this.interval=interval;
		this.beep=beep;
	}
	
	public void start() {
		ActionListener listener=new TimePrinter();
		Timer t=new Timer(interval,listener);
		t.start();
	}
	
	private class TimePrinter implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			System.out.println("現在時間是:"+new Date());
			if(beep) {
				Toolkit.getDefaultToolkit().beep();
			}
		}
	}
}

運行結果:


對於第二種內部類--局部內部類,其實是定義在類方法中的內部類,這種類不能使用訪問修飾符,而且這種類的作用域被限制在聲明這個局部類的塊中。同一般的內部類相比,局部內部類還有一個優勢就是可以訪問局部變量。

例如上面的代碼可以修改爲:

代碼:

package InnerClasses;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class InnerClassTest {
	public static void main(String[] args) {
		TalkingClock clock = new TalkingClock(1000,true);
		clock.start();
		
		JOptionPane.showMessageDialog(null,"關閉??");
		System.exit(0);
	}
}

class TalkingClock{
	private int interval;
	private boolean beep;
	
	public TalkingClock(int interval,boolean beep) {
		this.interval=interval;
		this.beep=beep;
	}
	
	public void start() {
		
		class TimePrinter implements ActionListener{
			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.out.println("現在時間是:"+new Date());
				if(beep) {
					Toolkit.getDefaultToolkit().beep();
				}
			}
		}
		
		ActionListener listener=new TimePrinter();
		Timer t=new Timer(interval,listener);
		t.start();
	}
}

輸出結果和上一例子一樣。


第三種內部類--匿名內部類:

這種內部類更加直接,沒有類名。

具體語法爲:

類名 對象名=new 類名(構造參數){

    內部類方法和數據

}

類名也可以是接口名,如果是接口名,則就像下面這樣子了:

接口名 對象名=new 接口名(){

    方法和數據

}

下面是一個例子:

package InnerClasses;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class AnonyInnerClassTest {
	public static void main(String[] args) {
		TalkingClock2 clock =new TalkingClock2();
		clock.start(1000, true);
		JOptionPane.showMessageDialog(null, "退出??");
		System.exit(0);
	}
}

class TalkingClock2{
	public void start(int interval,boolean beep) {
		ActionListener listener=new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.out.println("現在的時間是:"+new Date());
				if(beep) {
					Toolkit.getDefaultToolkit().beep();
				}
			}
			
		};
		
		Timer t=new Timer(interval,listener);
		t.start();
	}
}

運行結果和前兩個例子一樣。


第四種內部類--靜態內部類

靜態內部類的目的很簡單,就是爲了把一個類隱藏在另一個類的內部。這時,可以將內部類聲明爲static。

靜態內部類中不可以引用外部類的非靜態變量和方法,而在靜態內部類中可以有靜態域和靜態方法。

下面是一個例子:用於計算一個double型數組的最大值和最小值。

代碼:

package InnerClasses;

public class StaticInnerClass {
	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{
	public static class Pair{
		private double first;
		private double second;
		
		public Pair(double f,double s) {
			first=f;
			second=s;
		}
		
		public double getFirst() {
			return first;
		}
		
		public double getSecond() {
			return second;
		}
	}
	
	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);
	}
}

運行結果:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章