Java SE: Inner Class_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java SE: Inner Class

Java SE: Inner Class

 2014/5/23 19:09:43  DavyJones2010  程序员俱乐部  我要评论(0)
  • 摘要:1)WhywouldweuseInnserClass?1>Innerclassmethodscanaccessthedatafromthescopeinwhichtheyaredefined-includingdatathatwouldotherwisebeprivate.2>Innerclassescanbehiddenfromotherclassesinthesamepackage.3>
  • 标签:Java class

1) Why would we use InnserClass?

? ? 1> Inner class methods can access the data from the scope in which they are defined - including data that would otherwise be private.

? ? 2> Inner classes can be hidden from other classes in the same package.

? ? 3> Anonymous inner class are handy when you want to define callbacks without writing a lot of code.

?

Example for "InnerClass Access the Data Of OutterClass"

package edu.xmu.inner;

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

import javax.swing.Timer;

public class TalkingClock {
    private boolean shouldBeep;
    private int interval;

    public TalkingClock(boolean shouldBeep, int interval) {
	super();
	this.shouldBeep = shouldBeep;
	this.interval = interval;
    }

    public void start() {
	TimePrinter printer = new TimePrinter();
	Timer t = new Timer(interval, printer);
	t.start();
    }

    class TimePrinter implements ActionListener {
	@Override
	public void actionPerformed(ActionEvent e) {
	    Date date = new Date();
	    System.out.println("At the tone, the time is: " + date);
	    if (shouldBeep) { // Here inner get access to the property of outter
			      // class directly
		Toolkit.getDefaultToolkit().beep();
	    }
	}

	public int getInterval() {
	    return interval;
	}
    }

    public void test() {
	// Here we created an InnerClass without an instance of OutterClass
	// The reason is that the instance of OutterClass is "this" and don't
	// have to declare explicitly

	// TimePrinter printer = new TalkingClock.TimePrinter();
	// TimePrinter printer = this.new TimePrinter();
	TimePrinter printer = new TimePrinter();

	System.out.println(printer.getInterval());
    }
}

class AnotherClass {
    public void print() {
	TalkingClock clock = new TalkingClock(false, 1000);
	// InnerClass will not be created without OutterClass
	// If TimePrinter is private inner class, we cannot create it even with
	// instance of OutterClass
	TalkingClock.TimePrinter printer = clock.new TimePrinter();
	System.out.println(printer.getInterval());
    }
}

? ? Thus we can conclude that "InnerClass cannot exists/created without Instance of OutterClass".

? ? 1> Only InnerClass can be private. Regular classes always have either package or public visibility.

?

Example for: "Local InnerClass"

package edu.xmu.inner;

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

import javax.swing.Timer;

public class TalkingClock {
    private boolean shouldBeep;
    private int interval;

    public TalkingClock(boolean shouldBeep, int interval) {
	super();
	this.shouldBeep = shouldBeep;
	this.interval = interval;
    }

    public void start() {
	class TimePrinter implements ActionListener {
	    @Override
	    public void actionPerformed(ActionEvent e) {
		Date date = new Date();
		System.out.println("At the tone, the time is: " + date);
		if (shouldBeep) {
		    Toolkit.getDefaultToolkit().beep();
		}
	    }
	}

	TimePrinter printer = new TimePrinter();
	Timer t = new Timer(interval, printer);
	t.start();
    }
}

? ? 1) Local classes are never delcared with an access specifier(this is, public or private).

? ? ? ? Their scope is always restricted to the block(especially, method block) in which they are declared.

? ? 2) Local classes have a great advantage: they are completely hidden from the outside world-not even other code in the TalkingClock class can access them.

? ? ? ? No method except start() has any knowledge of the TimePrinter class.

? ? 3) However, those local variables must be declared final.

    public void start(final Date endDate) {
	class TimePrinter implements ActionListener {
	    @Override
	    public void actionPerformed(ActionEvent e) {
		Date date = new Date();
		if (date.before(endDate)) {
		    System.out.println("At the tone, the time is: " + date);
		    if (shouldBeep) {
			Toolkit.getDefaultToolkit().beep();
		    }
		}
	    }
	}
	TimePrinter printer = new TimePrinter();
	Timer t = new Timer(interval, printer);
	t.start();
    }

? ? ? ?Why should the variable endDate declared as final?

Step1> The start method is called.
Step2> The printer instance is initialized by a call to the constructor of InnerClass TimePrinter.
Step3> The printer instance is passed to the Timer constructor, the timer is started, and the start(Date) method exits.
At this point, the endDate parameter variable of the start(Date) method no longer exists.
Step4> 1000ms later, the actionPerformed method executes if(date.before(endDate))...

Thus, for the code in actionPerformed method to work, the TimerPrinter class must have copied the endDate field as a local variable of start method before the endDate field went away.

?

Example for "Anonymous Inner Class"

    public void start(final Date endDate) {
	Timer t = new Timer(interval, new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent e) {
		Date date = new Date();
		if (date.before(endDate)) {
		    System.out.println("At the tone, the time is: " + date);
		    if (shouldBeep) {
			Toolkit.getDefaultToolkit().beep();
		    }
		}
	    }
	});
	t.start();
    }

2) Static Inner Class

? ? 1> Occasionally, you want to use an inner class simply to hide one class inside another,

? ? ? ? ?but you don't need the inner class to have a reference to the instance of outer class.

? ? ? ? ?You can suppress the generation of that reference by declaring the inner class "static".

? ? ?2> Static Inner Class is also called Nested Class.

Example for "Static Inner Class":

? ? We need to get the max and min value in an array at the same time.

? ? If do not use Static Inner Class, we have to traverse the array twice.

package edu.xmu.inner;

public class InnerClassTest {
    public static void main(String[] args) {
	Calculator calculator = new Calculator();
	double[] values = { 1.1, 2.2, 3.3, 4.4, 0, -1.1, -2.2, -3.3, -4.4 };
	double max = calculator.getMax(values);
	double min = calculator.getMin(values);
	System.out.println("max = " + max + ", min = " + min);
    }
}

class Calculator {
    public double getMax(double[] values) {
	double max = Double.MIN_VALUE;
	for (double value : values) {
	    if (value > max) {
		max = value;
	    }
	}
	return max;
    }

    public double getMin(double[] values) {
	double min = Double.MAX_VALUE;
	for (double value : values) {
	    if (value < min) {
		min = value;
	    }
	}
	return min;
    }
}

? ? Use Static Inner Class:

package edu.xmu.inner;

import edu.xmu.inner.Calculator.Pair;

public class InnerClassTest {
    public static void main(String[] args) {
	Calculator calculator = new Calculator();
	double[] values = { 1.1, 2.2, 3.3, 4.4, 0, -1.1, -2.2, -3.3, -4.4 };
	Pair pair = calculator.getMaxAndMin(values);
	System.out.println("max = " + pair.getMax() + ", min = "
		+ pair.getMin());
    }
}

class Calculator {
    public Pair getMaxAndMin(double[] values) {
	double max = Double.MIN_VALUE;
	double min = Double.MAX_VALUE;

	for (double value : values) {
	    if (value < min) {
		min = value;
	    }
	    if (value > max) {
		max = value;
	    }
	}
	return new Pair(max, min);
    }

    static class Pair {
	double max;
	double min;

	public Pair(double max, double min) {
	    super();
	    this.max = max;
	    this.min = min;
	}

	public double getMax() {
	    return max;
	}

	public double getMin() {
	    return min;
	}
    }
}

? ? Benefits:

? ? ? ? 1> The name Pair is an exceedingly common name.

? ? ? ? ? ? ?And in a large project, it is quite possible that other module has the same named class but for different purpose.

? ? ? ? ? ? ?We can solve this potential name clash by making Pair a public inner class inside?Calculator.

? ? ? ? ? ? ?Then the class will be know to the public as Calculator.Pair

? ? ?Also, we can refer to Map.EntrySet<K, V> as a justification.

public class InnerClassTest {
    public static void main(String[] args) {
	Map<String, String> map = new HashMap<String, String>();
	map.put("A", "Hello");
	map.put("B", "Hallo");

	for (Map.Entry<String, String> entry : map.entrySet()) {
	    System.out.println(entry.getKey() + " = " + entry.getValue());
	}
    }
}
发表评论
用户名: 匿名