Inner Class内部类
什么是 ‘内'. 什么是 '外’.
有内就有外!这是相对而言的
Inner Class(内部类) 也一样, 是嵌套在一个Class的里面
如同你想的一样, 把一个Class放置于另一个Class的里面既是Inner Class内部类了
public class Parcel1 {
public class Contents{ //内部类
private int i = 11;
public int value(){//Contents方法
return i;
}
}
class Destination{//内部类
private String label;
Destination(String whereTo){//构造函数
label = whereTo;
}
String readLabel() {//Destination内方法
return label;
}
}
public void ship(String dest){
Contents c = new Contents();
Destination d = new Destination(dest);
//因为该Class只创建了一个构造函数还是有参的所以必须传入对应类型的参数(dest)
System.out.println(d.readLabel());
}
public static void main(String args){
Parcel1 p = new Parcel1();
p.ship("Tasmania");//方法声明的是String 类型, 所以必须传入对应类型
}
}
可看到在ship()方法中实例化了两个不同的对象,但这并没有报错, 也就证明目前所看的状况是在方法内实例化innerClass(内部类)对象与使用外部类实例化对象是没有区别, 但目前的区别是这个Class是在另一个Class的里面
public void ship(String dest){
Contents c = new Contents();
Destination d = new Destination(dest);
//因为该Class只创建了一个构造函数还是有参的所以必须传入对应类型的参数(dest)
System.out.println(d.readLabel());
}
普通内部类的访问存取权
↓
public class Sequence {
private Object[] items;
private int next = 0;
public Sequence(int size){//构造函数
items = new Object[size];
}
public void add(Object x){//Sequence方法
if(next < items.length){
items[next++] = x;
}
}
//创建私有内部类并实现接口
private class SequenceSelerctor implements Selector{
private int i = 0;
@Override
public boolean end() {
return i == items.length;
}
@Override
public Object current() {
return items[i];
}
@Override
public void next() {
if(i < items.length) i++;
}
}
private Selector selector(){
return new SequenceSelerctor();
}
public static void main(String[] args){
Sequence sequence = new Sequence(10);
for(int i = 0; i < 10; i++){
sequence.add(i);
}
Selector selector = sequence.selector();
while(!selector.end()){
System.out.print(selector.current() + " ");
selector.next();
}
}
}
观察SequenceSelector类中的方法end()、current()、next()都用到了objects, 这时引用并非SequenceSelector的一部分, 而是EnclosingClassObject外部类被声明 private私有字段要知道正常其他外部类是无法访问私有成员的
//目的:测试private访问权
//条件:两类都非InnerClass类
//第一个类
public class Sequence02 {
private String name = "王俩";
String name2 = "张仨";
}
//第二个类
public class Sequence01 {
public static void main(String[] args){
Sequence02 sequence02 = new Sequence02();
//System.out.println(sequence02.name);//王俩就不让访问
System.out.println(sequence02.name2);//看看人家张仨就行
}
}
那内部类为撒就能访问内部类的所有变量成员那:
当一个Class内创建另一个Class时也就是InnerClassObject时, InnerClassObject会偷偷摸摸的捕获一个指向外部类对象的一个引用. 然后访问外部对象时就是用的这个引用来选择外部类成员的
普通内部类的应用:
在编写应用程序使创建GUI后难免不会用到Button按钮, 但是只是单单的创建一个按钮并不能实现所需的功能(需要添加事件)这时候就可以使用内部的类来解决监听的实现. 这是内部类很常见, 实用, 且易于阅读的形式.因为内部是外部的一个成员.
public void goBuild(){
JFrame frame = new JFrame();
JButton button = new JButton();
frame.getContentPane().add(button);
button.addActionListener(new ButtonListener());//通常是传入一个内部的实例
}
public class ButtonListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
}
}
要记住这代表需要外部类的实例才能取得内部类的实例; 是指两个对象非内部与外部这种关系
Sequence02.Sequence sequence = new Sequence02.Sequence();
//你可能会如此调用Sequence02内的Sequence内部类
static静态类OR称之为嵌套类
跟在Class而不是特定实例对象的东西叫static静态; 静态嵌套的类看起跟用在事件监听者的非静态类很像, 但被标记为static
静态成员是跟Class一起被加载的包括static class,是独一份的!
区别:
- 普通的内部类对象隐式的保存了一个引用, 指向创建它的外部对象. 然而内部类是static静态时, 就不是这样了.
- 静态内部类可以包含静态成员也可以包含非静态成员, 非静态InnerClass则不阔以哦
- 静态内部类能直接访问外部类静态成员,而实例成员不能直接访问
- 静态内部类对象实例时不需要依赖外部对象, 可以通过 外部类.内部类.静态方法/成员; 而实例成员则需通过实例化才可访问
- 静态内部类调用如果是在外部调用静态内部类的静态成员直接:静态内部类名.静态成员; 静态内部类的实例成员还是得通过实例化才可调用